1 /* 2 * "GEDKeeper", the personal genealogical database editor. 3 * Copyright (C) 2009-2021 by Sergey V. Zhdanovskih. 4 * 5 * This file is part of "GEDKeeper". 6 * 7 * This program is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 using System; 22 using System.Collections.Generic; 23 using System.Diagnostics; 24 using System.Globalization; 25 using System.IO; 26 using System.Net; 27 using System.Reflection; 28 using System.Runtime.CompilerServices; 29 using System.Text; 30 using System.Text.RegularExpressions; 31 using BSLib; 32 using GDModel; 33 using GDModel.Providers.GEDCOM; 34 using GKCore.Cultures; 35 using GKCore.Import; 36 using GKCore.Interfaces; 37 using GKCore.Options; 38 using GKCore.Types; 39 using Ude; 40 41 namespace GKCore 42 { 43 /// <summary> 44 /// 45 /// </summary> 46 public static class GKUtils 47 { 48 #region Aux functions 49 50 /// <summary> 51 /// Forced call of GEDCOMProvider static constructor. 52 /// This is important for a number of tests that require initialization of the GEDCOM tag table. 53 /// And at the start of the application, before loading any GEDCOM files. 54 /// </summary> InitGEDCOM()55 public static void InitGEDCOM() 56 { 57 RuntimeHelpers.RunClassConstructor(typeof(GEDCOMProvider).TypeHandle); 58 } 59 GetCountries()60 public static List<string> GetCountries() 61 { 62 var countries = new List<string>(); 63 foreach (CultureInfo culture in CultureInfo.GetCultures(CultureTypes.SpecificCultures)) { 64 RegionInfo regionInfo = new RegionInfo(culture.LCID); 65 string ctry = regionInfo.TwoLetterISORegionName; // DisplayName 66 if (!countries.Contains(ctry)) 67 countries.Add(ctry); 68 } 69 countries.Sort(); 70 return countries; 71 } 72 LoadExtFile(string fileName, string args = R)73 public static void LoadExtFile(string fileName, string args = "") 74 { 75 #if !CI_MODE 76 if (File.Exists(fileName)) { 77 Process.Start(new ProcessStartInfo("file://"+fileName) { UseShellExecute = true, Arguments = args }); 78 } else { 79 Process.Start(fileName); 80 } 81 #endif 82 } 83 SexChar(GDMSex sex)84 public static string SexChar(GDMSex sex) 85 { 86 string ss = SexStr(sex); 87 return string.IsNullOrEmpty(ss) ? "?" : new string(ss[0], 1); 88 } 89 SexStr(GDMSex sex)90 public static string SexStr(GDMSex sex) 91 { 92 return LangMan.LS(GKData.SexData[(int)sex].NameId); 93 } 94 GetSexBySign(char sexSign)95 public static GDMSex GetSexBySign(char sexSign) 96 { 97 GDMSex result = GDMSex.svUnknown; 98 switch (sexSign) { 99 case 'F': 100 result = GDMSex.svFemale; 101 break; 102 case 'M': 103 result = GDMSex.svMale; 104 break; 105 case 'U': 106 result = GDMSex.svUnknown; 107 break; 108 case 'X': 109 result = GDMSex.svIntersex; 110 break; 111 } 112 return result; 113 } 114 MergeStrings(GDMLines strings)115 public static string MergeStrings(GDMLines strings) 116 { 117 if (strings == null) 118 throw new ArgumentNullException("strings"); 119 120 StringBuilder result = new StringBuilder(); 121 122 int num = strings.Count; 123 for (int i = 0; i < num; i++) { 124 if (result.Length != 0) result.Append(" "); 125 result.Append(strings[i].Trim()); 126 } 127 128 return result.ToString(); 129 } 130 TruncateStrings(GDMLines value, int size)131 public static string TruncateStrings(GDMLines value, int size) 132 { 133 string s = string.Empty; 134 135 if (value != null && value.Count != 0) { 136 if (size < value[0].Length) { 137 s = value[0].Substring(0, size) + "..."; 138 } else { 139 s = value[0]; 140 } 141 } 142 143 return s; 144 } 145 GetLocationLinks(GDMTree tree, GDMLocationRecord locRec)146 public static StringList GetLocationLinks(GDMTree tree, GDMLocationRecord locRec) 147 { 148 var linksList = new StringList(); 149 if (locRec == null) return linksList; 150 151 int num = tree.RecordsCount; 152 for (int i = 0; i < num; i++) { 153 var evsRec = tree[i] as GDMRecordWithEvents; 154 if (evsRec == null || !evsRec.HasEvents) continue; 155 156 int num2 = evsRec.Events.Count; 157 for (int j = 0; j < num2; j++) { 158 GDMCustomEvent evt = evsRec.Events[j]; 159 160 if (evt.HasPlace && evt.Place.Location.XRef == locRec.XRef) { 161 linksList.AddObject(GetRecordName(tree, evsRec, true) + ", " + GetEventName(evt).ToLower(), evsRec); 162 } 163 } 164 } 165 166 return linksList; 167 } 168 HyperLink(string xref, string text, int num)169 public static string HyperLink(string xref, string text, int num) 170 { 171 string result = ""; 172 173 if (!string.IsNullOrEmpty(xref) && string.IsNullOrEmpty(text)) { 174 text = "???"; 175 } 176 177 if (!string.IsNullOrEmpty(xref) && !string.IsNullOrEmpty(text)) { 178 result = "[url=" + xref + "]" + text + "[/url]"; 179 } 180 181 return result; 182 } 183 184 // TODO: greedy function, move to BaseContext GetRecordName(GDMTree tree, GDMRecord record, bool signed)185 public static string GetRecordName(GDMTree tree, GDMRecord record, bool signed) 186 { 187 string result = ""; 188 189 if (record != null) { 190 string sign = ""; 191 192 if (signed) { 193 GDMRecordType recordType = record.RecordType; 194 if (recordType != GDMRecordType.rtIndividual) { 195 if (recordType == GDMRecordType.rtFamily || (byte)recordType - (byte)GDMRecordType.rtMultimedia < (byte)GDMRecordType.rtResearch) 196 { 197 sign = LangMan.LS(GKData.RecordTypes[(int)record.RecordType]) + ": "; 198 } 199 } else { 200 sign = ""; 201 } 202 } 203 204 string st; 205 switch (record.RecordType) { 206 case GDMRecordType.rtIndividual: 207 st = GetNameString(((GDMIndividualRecord)record), true, false); 208 break; 209 case GDMRecordType.rtFamily: 210 st = GetFamilyString(tree, (GDMFamilyRecord)record); 211 break; 212 case GDMRecordType.rtNote: 213 st = ((GDMNoteRecord)record).Lines[0]; // TODO: bad solution?! 214 break; 215 case GDMRecordType.rtMultimedia: 216 st = ((GDMMultimediaRecord)record).FileReferences[0].Title; 217 break; 218 case GDMRecordType.rtSource: 219 st = ((GDMSourceRecord)record).ShortTitle; 220 break; 221 case GDMRecordType.rtRepository: 222 st = ((GDMRepositoryRecord)record).RepositoryName; 223 break; 224 case GDMRecordType.rtGroup: 225 st = ((GDMGroupRecord)record).GroupName; 226 break; 227 case GDMRecordType.rtResearch: 228 st = ((GDMResearchRecord)record).ResearchName; 229 break; 230 case GDMRecordType.rtTask: 231 st = GetTaskGoalStr(tree, (GDMTaskRecord)record); 232 break; 233 case GDMRecordType.rtCommunication: 234 st = ((GDMCommunicationRecord)record).CommName; 235 break; 236 case GDMRecordType.rtLocation: 237 st = ((GDMLocationRecord)record).LocationName; 238 break; 239 default: 240 st = record.XRef; 241 break; 242 } 243 244 result = sign + st; 245 } 246 247 return result; 248 } 249 GenRecordLink(GDMTree tree, GDMRecord record, bool signed)250 public static string GenRecordLink(GDMTree tree, GDMRecord record, bool signed) 251 { 252 string result = ""; 253 254 if (record != null) { 255 result = HyperLink(record.XRef, GetRecordName(tree, record, signed), 0); 256 } 257 258 return result; 259 } 260 GenRecordLinkTuple(GDMTree tree, GDMRecord record, bool signed)261 public static Tuple<string, string> GenRecordLinkTuple(GDMTree tree, GDMRecord record, bool signed) 262 { 263 if (record != null) { 264 string recName = GetRecordName(tree, record, signed); 265 string recLink = HyperLink(record.XRef, recName, 0); 266 return new Tuple<string, string>(recName, recLink); 267 } else { 268 return new Tuple<string, string>(string.Empty, string.Empty); 269 } 270 } 271 GetCorresponderStr(GDMTree tree, GDMCommunicationRecord commRec, bool aLink)272 public static string GetCorresponderStr(GDMTree tree, GDMCommunicationRecord commRec, bool aLink) 273 { 274 if (tree == null) 275 throw new ArgumentNullException("tree"); 276 277 if (commRec == null) 278 throw new ArgumentNullException("commRec"); 279 280 string result = ""; 281 var corr = tree.GetPtrValue(commRec.Corresponder); 282 283 if (corr != null) { 284 string nm = GetNameString(corr, true, false); 285 if (aLink) { 286 nm = HyperLink(corr.XRef, nm, 0); 287 } 288 result = "[ " + LangMan.LS(GKData.CommunicationDirs[(int)commRec.CommDirection]) + " ] " + nm; 289 } 290 return result; 291 } 292 293 public sealed class TaskGoalRet 294 { 295 public readonly GDMGoalType GoalType; 296 public readonly string GoalXRef; 297 public readonly GDMRecord GoalRec; 298 TaskGoalRet(GDMGoalType goalType, string goalXRef, GDMRecord goalRec)299 public TaskGoalRet(GDMGoalType goalType, string goalXRef, GDMRecord goalRec) 300 { 301 GoalType = goalType; 302 GoalXRef = goalXRef; 303 GoalRec = goalRec; 304 } 305 } 306 307 // TODO: greedy function, move to BaseContext GetTaskGoal(GDMTree tree, GDMTaskRecord taskRec)308 public static TaskGoalRet GetTaskGoal(GDMTree tree, GDMTaskRecord taskRec) 309 { 310 string goalXRef = string.Empty; 311 GDMRecord goalRec = tree.XRefIndex_Find(GEDCOMUtils.CleanXRef(taskRec.Goal)); 312 313 GDMGoalType goalType; 314 if (goalRec == null) { 315 goalType = GDMGoalType.gtOther; 316 } else { 317 switch (goalRec.RecordType) { 318 case GDMRecordType.rtIndividual: 319 goalType = GDMGoalType.gtIndividual; 320 break; 321 case GDMRecordType.rtFamily: 322 goalType = GDMGoalType.gtFamily; 323 break; 324 case GDMRecordType.rtSource: 325 goalType = GDMGoalType.gtSource; 326 break; 327 default: 328 goalType = GDMGoalType.gtOther; 329 break; 330 } 331 } 332 333 return new TaskGoalRet(goalType, goalXRef, goalRec); 334 } 335 GetTaskGoalStr(GDMTree tree, GDMTaskRecord taskRec)336 public static string GetTaskGoalStr(GDMTree tree, GDMTaskRecord taskRec) 337 { 338 if (tree == null || taskRec == null) return string.Empty; 339 340 string result = ""; 341 342 var goal = GetTaskGoal(tree, taskRec); 343 344 switch (goal.GoalType) { 345 case GDMGoalType.gtIndividual: 346 case GDMGoalType.gtFamily: 347 case GDMGoalType.gtSource: 348 result = GetGoalStr(tree, goal.GoalType, goal.GoalRec); 349 break; 350 351 case GDMGoalType.gtOther: 352 result = taskRec.Goal; 353 break; 354 } 355 356 if (goal.GoalType != GDMGoalType.gtOther) { 357 result = "[" + LangMan.LS(GKData.GoalNames[(int)goal.GoalType]) + "] " + result; 358 } 359 360 return result; 361 } 362 GetGoalStr(GDMTree tree, GDMGoalType gt, GDMRecord tempRec)363 public static string GetGoalStr(GDMTree tree, GDMGoalType gt, GDMRecord tempRec) 364 { 365 if (tempRec == null) return string.Empty; 366 367 switch (gt) 368 { 369 case GDMGoalType.gtIndividual: 370 return GetNameString(((GDMIndividualRecord)tempRec), true, false); 371 372 case GDMGoalType.gtFamily: 373 return GetFamilyString(tree, tempRec as GDMFamilyRecord); 374 375 case GDMGoalType.gtSource: 376 return ((GDMSourceRecord)tempRec).ShortTitle; 377 } 378 379 return string.Empty; 380 } 381 GetGroups(GDMTree tree)382 public static List<GDMGroupRecord> GetGroups(GDMTree tree) 383 { 384 var result = new List<GDMGroupRecord>(); 385 386 int num = tree.RecordsCount; 387 for (int i = 0; i < num; i++) { 388 var rec = tree[i] as GDMGroupRecord; 389 if (rec != null) { 390 result.Add(rec); 391 } 392 } 393 result.Sort((a, b) => -b.GroupName.CompareTo(a.GroupName)); 394 395 return result; 396 } 397 GetSources(GDMTree tree)398 public static List<GDMSourceRecord> GetSources(GDMTree tree) 399 { 400 var result = new List<GDMSourceRecord>(); 401 402 for (int i = 0; i < tree.RecordsCount; i++) { 403 var rec = tree[i] as GDMSourceRecord; 404 if (rec != null) { 405 result.Add(rec); 406 } 407 } 408 result.Sort((a, b) => -b.ShortTitle.CompareTo(a.ShortTitle)); 409 410 return result; 411 } 412 413 #endregion 414 415 #region Encoding 416 GetRectUID(int x1, int y1, int x2, int y2)417 public static string GetRectUID(int x1, int y1, int x2, int y2) 418 { 419 byte[] bx1 = BitConverter.GetBytes((ushort)x1); 420 byte[] by1 = BitConverter.GetBytes((ushort)y1); 421 byte[] bx2 = BitConverter.GetBytes((ushort)x2); 422 byte[] by2 = BitConverter.GetBytes((ushort)y2); 423 424 byte[] buffer = new byte[8]; 425 Buffer.BlockCopy(bx1, 0, buffer, 0, 2); 426 Buffer.BlockCopy(by1, 0, buffer, 2, 2); 427 Buffer.BlockCopy(bx2, 0, buffer, 4, 2); 428 Buffer.BlockCopy(by2, 0, buffer, 6, 2); 429 430 return GEDCOMUtils.EncodeUID(buffer); 431 } 432 DetectCharset(Stream stream, int bufferSize = 32768)433 public static CharsetResult DetectCharset(Stream stream, int bufferSize = 32768) 434 { 435 var result = new CharsetResult(); 436 437 ICharsetDetector cdet = new CharsetDetector(); 438 byte[] buffer = new byte[bufferSize]; 439 int read = stream.Read(buffer, 0, buffer.Length); 440 if (read > 0) { 441 cdet.Feed(buffer, 0, read); 442 cdet.DataEnd(); 443 stream.Seek(0, SeekOrigin.Begin); 444 445 result.Charset = cdet.Charset; 446 result.Confidence = cdet.Confidence; 447 } else { 448 result.Charset = null; 449 result.Confidence = 0.0f; 450 } 451 452 return result; 453 } 454 GetDetectedStreamReader(Stream stream)455 public static StreamReader GetDetectedStreamReader(Stream stream) 456 { 457 // TODO: total search and fix references to Encoding.GetEncoding(1251) 458 // TODO: implement detection of encoding 459 StreamReader reader = new StreamReader(stream, Encoding.GetEncoding(1251)); 460 return reader; 461 } 462 463 #endregion 464 465 #region Match functions 466 467 private static readonly char[] MaskDelimiters = { '*', '?', '|' }; 468 PrepareMask(string mask)469 public static string PrepareMask(string mask) 470 { 471 string regexStr = ""; 472 473 if (!string.IsNullOrEmpty(mask)) { 474 // double star evokes monstrous lags 475 mask = mask.Replace("**", "*").Replace("??", "?"); 476 477 int curPos = 0; 478 int len = mask.Length; 479 480 while (curPos < len) { 481 int I = mask.IndexOfAny(MaskDelimiters, curPos); 482 if (I < curPos) break; 483 if (I > curPos) { 484 string part = mask.Substring(curPos, I - curPos); 485 regexStr += Regex.Escape(part); 486 } 487 488 switch (mask[I]) { 489 case '*': 490 regexStr += ".*"; 491 break; 492 case '?': 493 regexStr += "."; 494 break; 495 case '|': 496 regexStr += "|"; 497 break; 498 } 499 500 curPos = I + 1; 501 } 502 503 if (curPos < len) { 504 string part = mask.Substring(curPos, len - curPos); 505 regexStr += Regex.Escape(part); 506 } 507 } 508 509 return regexStr; 510 } 511 512 public const RegexOptions RegexOpts = RegexOptions.Compiled | RegexOptions.IgnoreCase; 513 InitMaskRegex(string mask)514 public static Regex InitMaskRegex(string mask) 515 { 516 Regex result = null; 517 518 string regexStr = PrepareMask(mask); 519 if (!string.IsNullOrEmpty(regexStr)) { 520 result = new Regex(regexStr, RegexOpts); 521 } 522 523 return result; 524 } 525 MatchesRegex(string str, Regex regex)526 public static bool MatchesRegex(string str, Regex regex) 527 { 528 return (regex != null) && regex.IsMatch(str, 0); 529 } 530 MatchesMask(string str, string mask)531 public static bool MatchesMask(string str, string mask) 532 { 533 if (string.IsNullOrEmpty(str) || string.IsNullOrEmpty(mask)) { 534 return false; 535 } 536 537 if (mask == "*") { 538 return true; 539 } 540 541 // Regex.IsMatch() has caching 542 return Regex.IsMatch(str, PrepareMask(mask), RegexOpts); 543 } 544 545 #endregion 546 547 #region Event Utils 548 GetAttributeValue(GDMIndividualRecord iRec, string attrName)549 public static string GetAttributeValue(GDMIndividualRecord iRec, string attrName) 550 { 551 if (iRec == null) return string.Empty; 552 553 GDMCustomEvent attr = iRec.FindEvent(attrName); 554 string result = ((attr == null) ? "" : attr.StringValue); 555 return result; 556 } 557 GetPersonEventKindBySign(string sign)558 public static PersonEventKind GetPersonEventKindBySign(string sign) 559 { 560 int idx = GetPersonEventIndex(sign); 561 return (idx < 0) ? PersonEventKind.ekFact : GKData.PersonEvents[idx].Kind; 562 } 563 GetPersonEventIndex(string sign)564 public static int GetPersonEventIndex(string sign) 565 { 566 int res = -1; 567 568 for (int i = 0; i < GKData.PersonEvents.Length; i++) 569 { 570 if (GKData.PersonEvents[i].Sign == sign) 571 { 572 res = i; 573 break; 574 } 575 } 576 577 return res; 578 } 579 GetFamilyEventIndex(string sign)580 public static int GetFamilyEventIndex(string sign) 581 { 582 int res = -1; 583 584 for (int i = 0; i < GKData.FamilyEvents.Length; i++) 585 { 586 if (GKData.FamilyEvents[i].Sign == sign) 587 { 588 res = i; 589 break; 590 } 591 } 592 593 return res; 594 } 595 GetEventName(GDMCustomEvent evt)596 public static string GetEventName(GDMCustomEvent evt) 597 { 598 if (evt == null) 599 throw new ArgumentNullException("evt"); 600 601 string result = ""; 602 603 var evtName = evt.GetTagName(); 604 if (evt is GDMIndividualEvent || evt is GDMIndividualAttribute) { 605 int ev = GetPersonEventIndex(evtName); 606 if (ev == 0) { 607 result = !string.IsNullOrEmpty(evt.Classification) ? evt.Classification : LangMan.LS(GKData.PersonEvents[ev].Name); 608 } else { 609 result = (ev > 0) ? LangMan.LS(GKData.PersonEvents[ev].Name) : evtName; 610 } 611 } else if (evt is GDMFamilyEvent) { 612 int ev = GetFamilyEventIndex(evtName); 613 if (ev == 0) { 614 result = evt.Classification; 615 } else { 616 result = (ev > 0) ? LangMan.LS(GKData.FamilyEvents[ev].Name) : evtName; 617 } 618 } 619 620 return result; 621 } 622 GetAttributeStr(GDMIndividualAttribute iAttr)623 public static string GetAttributeStr(GDMIndividualAttribute iAttr) 624 { 625 if (iAttr == null) 626 throw new ArgumentNullException("iAttr"); 627 628 var attrName = iAttr.GetTagName(); 629 int idx = GetPersonEventIndex(attrName); 630 string st; 631 if (idx == 0) { 632 st = iAttr.Classification; 633 } else { 634 st = (idx > 0) ? LangMan.LS(GKData.PersonEvents[idx].Name) : attrName; 635 } 636 637 string place = string.Empty; 638 if (iAttr.HasPlace) { 639 place = iAttr.Place.StringValue; 640 if (place != "") { 641 place = " [" + place + "]"; 642 } 643 } 644 return st + ": " + iAttr.StringValue + place; 645 } 646 GetEventDesc(GDMTree tree, GDMCustomEvent evt, bool hyperLink = true)647 public static string GetEventDesc(GDMTree tree, GDMCustomEvent evt, bool hyperLink = true) 648 { 649 if (evt == null) 650 throw new ArgumentNullException("evt"); 651 652 string dt = GEDCOMEventToDateStr(evt, GlobalOptions.Instance.DefDateFormat, false); 653 654 string place = string.Empty; 655 if (evt.HasPlace) { 656 place = evt.Place.StringValue; 657 GDMLocationRecord location = tree.GetPtrValue<GDMLocationRecord>(evt.Place.Location); 658 659 if (place != "" && location != null && hyperLink) { 660 place = HyperLink(location.XRef, place, 0); 661 } 662 } 663 664 string result; 665 666 if (dt == "" && place == "") { 667 result = "?"; 668 } else { 669 if (dt == "") { 670 result = place; 671 } else { 672 if (place == "") { 673 result = dt; 674 } else { 675 result = dt + ", " + place; 676 } 677 } 678 } 679 680 return result; 681 } 682 GetEventCause(GDMCustomEvent evt)683 public static string GetEventCause(GDMCustomEvent evt) 684 { 685 if (evt == null) 686 throw new ArgumentNullException("evt"); 687 688 string result = evt.Cause; 689 690 if (!string.IsNullOrEmpty(evt.Agency)) { 691 if (result != "") { 692 result += " "; 693 } 694 result = result + "[" + evt.Agency + "]"; 695 } 696 697 return result; 698 } 699 700 #endregion 701 702 #region Date functions 703 704 /// <summary> 705 /// The result of the function is a "normalized date", delimited by '.' and fixed order of parts: "dd.mm.yyyy". 706 /// The pattern and regional date contain the delimiter '/'. 707 /// The pattern defines the position of the parts in a regional date format. 708 /// </summary> 709 /// <param name="regionalDate">date similar "01/20/1970"</param> 710 /// <param name="pattern">pattern similar "mm/dd/yyyy"</param> 711 /// <returns>normalized date as "dd.mm.yyyy"</returns> GetNormalizeDate(string regionalDate, string pattern)712 public static string GetNormalizeDate(string regionalDate, string pattern) 713 { 714 if (string.IsNullOrEmpty(regionalDate)) return string.Empty; 715 716 string[] regionalParts = regionalDate.Split('/'); 717 string[] patternParts = pattern.Split('/'); 718 string[] resultParts = new string[3]; 719 720 for (int i = 0; i < patternParts.Length; i++) { 721 string part = patternParts[i]; 722 switch (part[0]) { 723 case 'd': 724 resultParts[0] = regionalParts[i]; 725 break; 726 727 case 'm': 728 resultParts[1] = regionalParts[i]; 729 break; 730 731 case 'y': 732 resultParts[2] = regionalParts[i]; 733 break; 734 } 735 } 736 737 string result = string.Join(".", resultParts); 738 return result; 739 } 740 741 /// <summary> 742 /// The result of the function is a "regional date", delimited by '/' and regional order of parts: "mm/dd/yyyy" 743 /// or any other. The pattern and regional date contain the delimiter '/'. 744 /// The pattern defines the position of the parts in a regional date format. 745 /// </summary> 746 /// <param name="normalizeDate">date with format "dd.mm.yyyy"</param> 747 /// <param name="pattern">pattern similar "mm/dd/yyyy"</param> 748 /// <returns>regional date as "mm/dd/yyyy"</returns> GetRegionalDate(string normalizeDate, string pattern)749 public static string GetRegionalDate(string normalizeDate, string pattern) 750 { 751 if (string.IsNullOrEmpty(normalizeDate)) return string.Empty; 752 753 string[] normalizeParts = normalizeDate.Split('.'); 754 string[] patternParts = pattern.Split('/'); 755 string[] resultParts = new string[3]; 756 757 for (int i = 0; i < patternParts.Length; i++) { 758 string part = patternParts[i]; 759 switch (part[0]) { 760 case 'd': 761 resultParts[i] = normalizeParts[0]; 762 break; 763 764 case 'm': 765 resultParts[i] = normalizeParts[1]; 766 break; 767 768 case 'y': 769 resultParts[i] = normalizeParts[2]; 770 break; 771 } 772 } 773 774 string result = string.Join("/", resultParts); 775 return result; 776 } 777 GEDCOMEventToDateStr(GDMCustomEvent evt, DateFormat format, bool sign)778 public static string GEDCOMEventToDateStr(GDMCustomEvent evt, DateFormat format, bool sign) 779 { 780 return (evt == null) ? string.Empty : evt.Date.GetDisplayStringExt(format, sign, false); 781 } 782 CompactDate(string date)783 public static string CompactDate(string date) 784 { 785 string result = date; 786 while (result.IndexOf("__.") == 0) result = result.Remove(0, 3); 787 return result; 788 } 789 GetBirthDate(GDMIndividualRecord iRec)790 public static GDMCustomDate GetBirthDate(GDMIndividualRecord iRec) 791 { 792 if (iRec == null) return null; 793 794 GDMCustomEvent evt = iRec.FindEvent(GEDCOMTagType.BIRT); 795 GDMCustomDate result = ((evt == null) ? null : evt.Date.Value); 796 return result; 797 } 798 GetBirthDate(GDMIndividualRecord iRec, DateFormat dateFormat, bool compact)799 public static string GetBirthDate(GDMIndividualRecord iRec, DateFormat dateFormat, bool compact) 800 { 801 if (iRec == null) return string.Empty; 802 803 GDMCustomEvent evt = iRec.FindEvent(GEDCOMTagType.BIRT); 804 string result = ((evt == null) ? "" : GEDCOMEventToDateStr(evt, dateFormat, false)); 805 if (compact) result = CompactDate(result); 806 return result; 807 } 808 GetDeathDate(GDMIndividualRecord iRec, DateFormat dateFormat, bool compact)809 public static string GetDeathDate(GDMIndividualRecord iRec, DateFormat dateFormat, bool compact) 810 { 811 if (iRec == null) return string.Empty; 812 813 GDMCustomEvent evt = iRec.FindEvent(GEDCOMTagType.DEAT); 814 string result = ((evt == null) ? "" : GEDCOMEventToDateStr(evt, dateFormat, false)); 815 if (compact) result = CompactDate(result); 816 return result; 817 } 818 GetLifeStr(GDMIndividualRecord iRec)819 public static string GetLifeStr(GDMIndividualRecord iRec) 820 { 821 if (iRec == null) return string.Empty; 822 823 string result = " ("; 824 825 string ds = GetBirthDate(iRec, GlobalOptions.Instance.DefDateFormat, false); 826 if (ds == "") 827 { 828 ds = "?"; 829 } 830 result += ds; 831 832 ds = GetDeathDate(iRec, GlobalOptions.Instance.DefDateFormat, false); 833 if (ds == "") 834 { 835 GDMCustomEvent ev = iRec.FindEvent(GEDCOMTagType.DEAT); 836 if (ev != null) 837 { 838 ds = "?"; 839 } 840 } 841 842 if (ds != "") 843 { 844 result = result + " - " + ds; 845 } 846 847 result += ")"; 848 return result; 849 } 850 GetEventDatePlace(GDMIndividualRecord iRec, string eventName, DateFormat dateFormat, bool compact, bool markUnkDate, out string dateStr, out string placeStr)851 public static void GetEventDatePlace(GDMIndividualRecord iRec, string eventName, DateFormat dateFormat, 852 bool compact, bool markUnkDate, out string dateStr, out string placeStr) 853 { 854 dateStr = string.Empty; 855 placeStr = string.Empty; 856 857 if (iRec != null) { 858 GDMCustomEvent evt = iRec.FindEvent(eventName); 859 if (evt != null) { 860 dateStr = GEDCOMEventToDateStr(evt, dateFormat, false); 861 if (dateStr != "") { 862 if (compact) dateStr = CompactDate(dateStr); 863 } 864 if (dateStr == "" && markUnkDate) { 865 dateStr = "?"; 866 } 867 868 placeStr = GetPlaceStr(evt, false); 869 } 870 } 871 } 872 GetPedigreeLifeStr(GDMIndividualRecord iRec, PedigreeFormat fmt)873 public static string GetPedigreeLifeStr(GDMIndividualRecord iRec, PedigreeFormat fmt) 874 { 875 if (iRec == null) 876 throw new ArgumentNullException("iRec"); 877 878 string result = ""; 879 880 switch (fmt) { 881 case PedigreeFormat.Excess: 882 { 883 string ds = GetBirthDate(iRec, GlobalOptions.Instance.DefDateFormat, true); 884 if (ds == "") 885 { 886 ds = "?"; 887 } 888 result += ds; 889 ds = GetDeathDate(iRec, GlobalOptions.Instance.DefDateFormat, true); 890 if (ds == "") 891 { 892 GDMCustomEvent ev = iRec.FindEvent(GEDCOMTagType.DEAT); 893 if (ev != null) 894 { 895 ds = "?"; 896 } 897 } 898 if (ds != "") 899 { 900 result = result + " - " + ds; 901 } 902 } 903 break; 904 905 case PedigreeFormat.Compact: 906 { 907 string ds, ps; 908 909 GetEventDatePlace(iRec, GEDCOMTagName.BIRT, GlobalOptions.Instance.DefDateFormat, true, true, out ds, out ps); 910 if (ps != "") { 911 if (ds != "") { 912 ds += ", "; 913 } 914 ds += ps; 915 } 916 if (ds != "") { 917 ds = ImportUtils.STD_BIRTH_SIGN + ds; 918 } 919 result += ds; 920 921 GetEventDatePlace(iRec, GEDCOMTagName.DEAT, GlobalOptions.Instance.DefDateFormat, true, true, out ds, out ps); 922 if (ps != "") { 923 if (ds != "") { 924 ds += ", "; 925 } 926 ds += ps; 927 } 928 if (ds != "") { 929 ds = ImportUtils.STD_DEATH_SIGN + ds; 930 result = result + " " + ds; 931 } 932 } 933 break; 934 } 935 936 result = result.Trim(); 937 result = (result == "") ? "" : " (" + result + ")"; 938 return result; 939 } 940 GetChronologicalYear(GDMCustomEvent evt)941 public static int GetChronologicalYear(GDMCustomEvent evt) 942 { 943 return (evt == null) ? 0 : evt.Date.GetChronologicalYear(); 944 } 945 GetEventsYearsDiff(GDMCustomEvent ev1, GDMCustomEvent ev2, bool currentEnd)946 public static int GetEventsYearsDiff(GDMCustomEvent ev1, GDMCustomEvent ev2, bool currentEnd) 947 { 948 int result = -1; 949 950 try { 951 int dt1 = GetChronologicalYear(ev1); 952 int dt2 = GetChronologicalYear(ev2); 953 954 if (currentEnd && dt2 == 0) { 955 dt2 = DateTime.Now.Year; 956 } 957 958 if (dt1 != 0 && dt2 != 0) { 959 result = Math.Abs(dt2 - dt1); 960 } 961 } catch (Exception ex) { 962 Logger.WriteError("GKUtils.GetEventsYearsDiff()", ex); 963 } 964 965 return result; 966 } 967 GetLifeExpectancyStr(GDMIndividualRecord iRec)968 public static string GetLifeExpectancyStr(GDMIndividualRecord iRec) 969 { 970 int result = GetLifeExpectancy(iRec); 971 return (result == -1) ? "" : result.ToString(); 972 } 973 GetLifeExpectancy(GDMIndividualRecord iRec)974 public static int GetLifeExpectancy(GDMIndividualRecord iRec) 975 { 976 int result = -1; 977 if (iRec == null) return result; 978 979 try { 980 var lifeDates = iRec.GetLifeDates(); 981 result = GetEventsYearsDiff(lifeDates.BirthEvent, lifeDates.DeathEvent, false); 982 } catch (Exception ex) { 983 Logger.WriteError("GKUtils.GetLifeExpectancy()", ex); 984 } 985 986 return result; 987 } 988 GetAgeStr(GDMIndividualRecord iRec, int toYear)989 public static string GetAgeStr(GDMIndividualRecord iRec, int toYear) 990 { 991 int result = GetAge(iRec, toYear); 992 return (result == -1) ? "" : result.ToString(); 993 } 994 GetAge(GDMIndividualRecord iRec, int toYear)995 public static int GetAge(GDMIndividualRecord iRec, int toYear) 996 { 997 int result = -1; 998 if (iRec == null) return result; 999 1000 try { 1001 var lifeDates = iRec.GetLifeDates(); 1002 1003 if (toYear == -1) { 1004 result = GetEventsYearsDiff(lifeDates.BirthEvent, lifeDates.DeathEvent, lifeDates.DeathEvent == null); 1005 } else { 1006 int birthYear = GetChronologicalYear(lifeDates.BirthEvent); 1007 if (birthYear != 0) { 1008 result = toYear - birthYear; 1009 } 1010 } 1011 } catch (Exception ex) { 1012 Logger.WriteError("GKUtils.GetAge()", ex); 1013 } 1014 1015 return result; 1016 } 1017 GetMarriageDate(GDMFamilyRecord fRec)1018 public static GDMCustomDate GetMarriageDate(GDMFamilyRecord fRec) 1019 { 1020 if (fRec == null) { 1021 return null; 1022 } 1023 1024 GDMCustomEvent evt = fRec.FindEvent(GEDCOMTagType.MARR); 1025 return ((evt == null) ? null : evt.Date.Value); 1026 } 1027 GetMarriageDateStr(GDMFamilyRecord fRec, DateFormat dateFormat, bool sign)1028 public static string GetMarriageDateStr(GDMFamilyRecord fRec, DateFormat dateFormat, bool sign) 1029 { 1030 GDMCustomDate date = GetMarriageDate(fRec); 1031 return (date == null) ? string.Empty : date.GetDisplayStringExt(dateFormat, sign, false); 1032 } GetMarriageDateStr(GDMFamilyRecord fRec, DateFormat dateFormat)1033 public static string GetMarriageDateStr(GDMFamilyRecord fRec, DateFormat dateFormat) 1034 { 1035 GDMCustomDate date = GetMarriageDate(fRec); 1036 return (date == null) ? string.Empty : date.GetDisplayStringExt(dateFormat, false, false); 1037 } 1038 1039 /// <summary> 1040 /// Get number of days remained until the birthday of the specified 1041 /// person. 1042 /// </summary> 1043 /// <param name="iRec">A person record to check.</param> 1044 /// <returns>Number of days remained until the birthday of 1045 /// the <paramref name="iRec" />. The caller must ignore this value if 1046 /// the method returns -1.</returns> GetDaysForBirth(GDMIndividualRecord iRec)1047 public static int GetDaysForBirth(GDMIndividualRecord iRec) 1048 { 1049 int distance = -1; 1050 1051 if (iRec != null) { 1052 int bdD, bdM, bdY; 1053 1054 try { 1055 GDMCustomEvent evt = iRec.FindEvent(GEDCOMTagType.DEAT); 1056 if (evt == null) { 1057 evt = iRec.FindEvent(GEDCOMTagType.BIRT); 1058 if (evt != null) { 1059 var dt = evt.Date.Value as GDMDate; 1060 if (dt != null) { 1061 bdM = dt.Month; 1062 bdD = dt.Day; 1063 1064 if (bdM != 0 && bdD != 0) { 1065 DateTime dtNow = DateTime.Now.Date; 1066 int curY = dtNow.Year; 1067 int curM = dtNow.Month; 1068 int curD = dtNow.Day; 1069 double dt2 = curY + bdM / 12.0 + bdD / 12.0 / 31.0; 1070 double dt3 = curY + curM / 12.0 + curD / 12.0 / 31.0; 1071 bdY = (dt2 < dt3) ? (curY + 1) : curY; 1072 1073 // There are valid birthdays on February 29th in leap years. 1074 // For other years, we need a correction for an acceptable day. 1075 if (bdD == 29 && bdM == 2 && !DateTime.IsLeapYear(bdY)) { 1076 bdD -= 1; 1077 } 1078 1079 distance = DateHelper.DaysBetween(dtNow, new DateTime(bdY, bdM, bdD)); 1080 } 1081 } 1082 } 1083 } 1084 } catch (Exception ex) { 1085 Logger.WriteError("GKUtils.GetDaysForBirth()", ex); 1086 } 1087 } 1088 1089 return distance; 1090 } 1091 1092 #endregion 1093 1094 #region Places functions 1095 GetBirthPlace(GDMIndividualRecord iRec)1096 public static string GetBirthPlace(GDMIndividualRecord iRec) 1097 { 1098 return (iRec == null) ? string.Empty : GetPlaceStr(iRec.FindEvent(GEDCOMTagType.BIRT), false); 1099 } 1100 GetDeathPlace(GDMIndividualRecord iRec)1101 public static string GetDeathPlace(GDMIndividualRecord iRec) 1102 { 1103 return (iRec == null) ? string.Empty : GetPlaceStr(iRec.FindEvent(GEDCOMTagType.DEAT), false); 1104 } 1105 GetResidencePlace(GDMIndividualRecord iRec, bool includeAddress)1106 public static string GetResidencePlace(GDMIndividualRecord iRec, bool includeAddress) 1107 { 1108 return (iRec == null) ? string.Empty : GetPlaceStr(iRec.FindEvent(GEDCOMTagType.RESI), includeAddress); 1109 } 1110 GetPlaceStr(GDMCustomEvent evt, bool includeAddress)1111 public static string GetPlaceStr(GDMCustomEvent evt, bool includeAddress) 1112 { 1113 if (evt == null || !evt.HasPlace) return string.Empty; 1114 1115 string result = evt.Place.StringValue; 1116 1117 if (includeAddress) { 1118 string resi = evt.StringValue; 1119 1120 if (evt.HasAddress) { 1121 string addrText = evt.Address.Lines.Text.Trim(); 1122 if (resi != "" && addrText != "") { 1123 resi += ", "; 1124 } 1125 resi += addrText; 1126 } 1127 1128 if (resi != "") { 1129 result = result + " [" + resi + "]"; 1130 } 1131 } 1132 1133 return result; 1134 } 1135 1136 #endregion 1137 1138 #region Individual functions 1139 GetAncestorsCount(GDMTree tree, GDMIndividualRecord iRec)1140 public static int GetAncestorsCount(GDMTree tree, GDMIndividualRecord iRec) 1141 { 1142 var indiCounters = new GKVarCache<GDMIndividualRecord, int>(-1); 1143 return GetAncestorsCount(tree, iRec, indiCounters); 1144 } 1145 GetAncestorsCount(GDMTree tree, GDMIndividualRecord iRec, GKVarCache<GDMIndividualRecord, int> counters)1146 private static int GetAncestorsCount(GDMTree tree, GDMIndividualRecord iRec, GKVarCache<GDMIndividualRecord, int> counters) 1147 { 1148 int result = 0; 1149 1150 if (iRec != null) { 1151 int val = counters[iRec]; 1152 1153 if (val < 0) { 1154 val = 1; 1155 1156 GDMFamilyRecord family = tree.GetParentsFamily(iRec); 1157 if (family != null) { 1158 GDMIndividualRecord anc; 1159 1160 anc = tree.GetPtrValue(family.Husband); 1161 val += GetAncestorsCount(tree, anc, counters); 1162 1163 anc = tree.GetPtrValue(family.Wife); 1164 val += GetAncestorsCount(tree, anc, counters); 1165 } 1166 1167 counters[iRec] = val; 1168 } 1169 1170 result = val; 1171 } 1172 1173 return result; 1174 } 1175 GetDescendantsCount(GDMTree tree, GDMIndividualRecord iRec)1176 public static int GetDescendantsCount(GDMTree tree, GDMIndividualRecord iRec) 1177 { 1178 var indiCounters = new GKVarCache<GDMIndividualRecord, int>(-1); 1179 return GetDescendantsCount(tree, iRec, indiCounters); 1180 } 1181 GetDescendantsCount(GDMTree tree, GDMIndividualRecord iRec, GKVarCache<GDMIndividualRecord, int> counters)1182 private static int GetDescendantsCount(GDMTree tree, GDMIndividualRecord iRec, GKVarCache<GDMIndividualRecord, int> counters) 1183 { 1184 int result = 0; 1185 1186 if (iRec != null) { 1187 int val = counters[iRec]; 1188 if (val < 0) { 1189 val = 1; 1190 1191 int num = iRec.SpouseToFamilyLinks.Count; 1192 for (int i = 0; i < num; i++) { 1193 GDMFamilyRecord family = tree.GetPtrValue(iRec.SpouseToFamilyLinks[i]); 1194 1195 int num2 = family.Children.Count; 1196 for (int j = 0; j < num2; j++) { 1197 GDMIndividualRecord child = tree.GetPtrValue(family.Children[j]); 1198 val += GetDescendantsCount(tree, child, counters); 1199 } 1200 } 1201 counters[iRec] = val; 1202 } 1203 result = val; 1204 } 1205 1206 return result; 1207 } 1208 GetDescGens_Recursive(GDMTree tree, GDMIndividualRecord iRec)1209 private static int GetDescGens_Recursive(GDMTree tree, GDMIndividualRecord iRec) 1210 { 1211 int result = 0; 1212 1213 if (iRec != null) { 1214 int max = 0; 1215 1216 int num = iRec.SpouseToFamilyLinks.Count; 1217 for (int i = 0; i < num; i++) { 1218 GDMFamilyRecord family = tree.GetPtrValue(iRec.SpouseToFamilyLinks[i]); 1219 1220 int num2 = family.Children.Count; 1221 for (int j = 0; j < num2; j++) { 1222 GDMIndividualRecord child = tree.GetPtrValue(family.Children[j]); 1223 int res = GetDescGens_Recursive(tree, child); 1224 if (max < res) { 1225 max = res; 1226 } 1227 } 1228 } 1229 result = 1 + max; 1230 } 1231 1232 return result; 1233 } 1234 GetDescGenerations(GDMTree tree, GDMIndividualRecord iRec)1235 public static int GetDescGenerations(GDMTree tree, GDMIndividualRecord iRec) 1236 { 1237 return GetDescGens_Recursive(tree, iRec) - 1; 1238 } 1239 GetMarriagesCount(GDMIndividualRecord iRec)1240 public static int GetMarriagesCount(GDMIndividualRecord iRec) 1241 { 1242 int result = ((iRec == null) ? 0 : iRec.SpouseToFamilyLinks.Count); 1243 return result; 1244 } 1245 GetSpousesDiff(GDMTree tree, GDMFamilyRecord fRec)1246 public static int GetSpousesDiff(GDMTree tree, GDMFamilyRecord fRec) 1247 { 1248 int result = -1; 1249 1250 try { 1251 if (fRec != null) { 1252 GDMIndividualRecord husb = tree.GetPtrValue(fRec.Husband); 1253 GDMIndividualRecord wife = tree.GetPtrValue(fRec.Wife); 1254 1255 if (husb != null && wife != null) { 1256 GDMCustomEvent evH = husb.FindEvent(GEDCOMTagType.BIRT); 1257 GDMCustomEvent evW = wife.FindEvent(GEDCOMTagType.BIRT); 1258 1259 result = GetEventsYearsDiff(evH, evW, false); 1260 } 1261 } 1262 } catch (Exception ex) { 1263 Logger.WriteError("GKUtils.GetSpousesDiff()", ex); 1264 } 1265 1266 return result; 1267 } 1268 GetFirstborn(GDMTree tree, GDMIndividualRecord iRec)1269 public static GDMIndividualRecord GetFirstborn(GDMTree tree, GDMIndividualRecord iRec) 1270 { 1271 GDMIndividualRecord iChild = null; 1272 if (iRec == null) return iChild; 1273 1274 try { 1275 int firstYear = 0; 1276 1277 int num = iRec.SpouseToFamilyLinks.Count; 1278 for (int i = 0; i < num; i++) { 1279 GDMFamilyRecord family = tree.GetPtrValue(iRec.SpouseToFamilyLinks[i]); 1280 if (family == null) continue; 1281 1282 int num2 = family.Children.Count; 1283 for (int j = 0; j < num2; j++) { 1284 GDMIndividualRecord child = tree.GetPtrValue(family.Children[j]); 1285 if (child == null) continue; 1286 1287 GDMCustomEvent evt = child.FindEvent(GEDCOMTagType.BIRT); 1288 if (evt == null) continue; 1289 1290 int childYear = evt.GetChronologicalYear(); 1291 1292 if (firstYear == 0) { 1293 firstYear = childYear; 1294 iChild = child; 1295 } else { 1296 if (firstYear > childYear) { 1297 firstYear = childYear; 1298 iChild = child; 1299 } 1300 } 1301 } 1302 } 1303 } catch (Exception ex) { 1304 Logger.WriteError("GKUtils.GetFirstborn()", ex); 1305 } 1306 return iChild; 1307 } 1308 GetFirstbornAge(GDMIndividualRecord iRec, GDMIndividualRecord iChild)1309 public static int GetFirstbornAge(GDMIndividualRecord iRec, GDMIndividualRecord iChild) 1310 { 1311 int result = 0; 1312 if (iRec == null || iChild == null) return result; 1313 1314 try { 1315 GDMCustomEvent evt = iRec.FindEvent(GEDCOMTagType.BIRT); 1316 if (evt == null) return result; 1317 int parentYear = evt.GetChronologicalYear(); 1318 1319 evt = iChild.FindEvent(GEDCOMTagType.BIRT); 1320 if (evt == null) return result; 1321 int childYear = evt.GetChronologicalYear(); 1322 1323 if (parentYear != 0 && childYear != 0) { 1324 result = (childYear - parentYear); 1325 } 1326 } catch (Exception ex) { 1327 Logger.WriteError("GKUtils.GetFirstbornAge()", ex); 1328 } 1329 return result; 1330 } 1331 GetMarriageAge(GDMTree tree, GDMIndividualRecord iRec)1332 public static int GetMarriageAge(GDMTree tree, GDMIndividualRecord iRec) 1333 { 1334 int result = 0; 1335 if (iRec == null) return result; 1336 1337 try { 1338 int firstYear = 0; 1339 1340 GDMCustomEvent evt = iRec.FindEvent(GEDCOMTagType.BIRT); 1341 if (evt != null) { 1342 int mainYear = evt.GetChronologicalYear(); 1343 1344 int num = iRec.SpouseToFamilyLinks.Count; 1345 for (int i = 0; i < num; i++) { 1346 GDMFamilyRecord family = tree.GetPtrValue(iRec.SpouseToFamilyLinks[i]); 1347 if (family == null) continue; 1348 1349 GDMCustomEvent marrEvt = family.FindEvent(GEDCOMTagType.MARR); 1350 if (marrEvt == null) continue; 1351 1352 int spouseYear = marrEvt.GetChronologicalYear(); 1353 1354 if (firstYear == 0) { 1355 firstYear = spouseYear; 1356 } else { 1357 if (firstYear > spouseYear) { 1358 firstYear = spouseYear; 1359 } 1360 } 1361 } 1362 1363 if (mainYear != 0 && firstYear != 0) { 1364 result = (firstYear - mainYear); 1365 } 1366 } 1367 } catch (Exception ex) { 1368 Logger.WriteError("GKUtils.GetMarriageAge()", ex); 1369 } 1370 return result; 1371 } 1372 1373 #endregion 1374 1375 #region Tree utils 1376 PrepareHeader(GDMTree tree, string fileName, GEDCOMCharacterSet charSet, bool zeroRev)1377 public static void PrepareHeader(GDMTree tree, string fileName, GEDCOMCharacterSet charSet, bool zeroRev) 1378 { 1379 GDMHeader header = tree.Header; 1380 1381 string subm = header.Submitter.XRef; 1382 int oldRev = header.File.Revision; 1383 GDMLanguageID langId = header.Language; 1384 1385 header.Clear(); 1386 header.Source.StringValue = "GEDKeeper"; 1387 header.ReceivingSystemName = "GEDKeeper"; 1388 header.CharacterSet.Value = charSet; 1389 header.Language = langId; 1390 header.GEDCOM.Version = "5.5.1"; 1391 header.GEDCOM.Form = "LINEAGE-LINKED"; 1392 header.File.StringValue = Path.GetFileName(fileName); 1393 header.TransmissionDateTime = DateTime.Now; 1394 1395 header.Source.Version = GKData.APP_FORMAT_CURVER.ToString(); 1396 1397 if (zeroRev) { 1398 header.File.Revision = 0; 1399 } else { 1400 header.File.Revision = oldRev + 1; 1401 } 1402 1403 if (!string.IsNullOrEmpty(subm)) { 1404 header.Submitter.XRef = subm; 1405 } 1406 } 1407 1408 #endregion 1409 1410 #region Folder functions 1411 GetTempDir()1412 public static string GetTempDir() 1413 { 1414 string tempPath = Environment.GetEnvironmentVariable("TEMP"); 1415 return tempPath + Path.DirectorySeparatorChar; 1416 } 1417 GetBinPath()1418 public static string GetBinPath() 1419 { 1420 Assembly asm = Assembly.GetEntryAssembly(); 1421 if (asm == null) { 1422 asm = Assembly.GetExecutingAssembly(); 1423 } 1424 1425 Module[] mods = asm.GetModules(); 1426 string fn = mods[0].FullyQualifiedName; 1427 return Path.GetDirectoryName(fn) + Path.DirectorySeparatorChar; 1428 } 1429 GetAppPath()1430 public static string GetAppPath() 1431 { 1432 string result = Path.GetFullPath(Path.Combine(GetBinPath(), @".." + Path.DirectorySeparatorChar)); 1433 return result; 1434 } 1435 GetPluginsPath()1436 public static string GetPluginsPath() 1437 { 1438 string appPath = GetAppPath(); 1439 return appPath + "plugins" + Path.DirectorySeparatorChar; 1440 } 1441 GetLangsPath()1442 public static string GetLangsPath() 1443 { 1444 string appPath = GetAppPath(); 1445 return appPath + "locales" + Path.DirectorySeparatorChar; 1446 } 1447 GetHelpPath(string langSign)1448 public static string GetHelpPath(string langSign) 1449 { 1450 string appPath = GetLangsPath(); 1451 return appPath + "help_" + langSign + Path.DirectorySeparatorChar; 1452 } 1453 GetBackgroundsPath()1454 public static string GetBackgroundsPath() 1455 { 1456 string appPath = GetAppPath(); 1457 return appPath + "backgrounds" + Path.DirectorySeparatorChar; 1458 } 1459 GetHomePath()1460 public static string GetHomePath() 1461 { 1462 string homePath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); 1463 return homePath + Path.DirectorySeparatorChar; 1464 } 1465 CopyFile(FileInfo source, FileInfo target, IProgressController progressController)1466 public static void CopyFile(FileInfo source, FileInfo target, IProgressController progressController) 1467 { 1468 using (var sourceStm = source.OpenRead()) { 1469 CopyFile(sourceStm, target, progressController); 1470 } 1471 } 1472 CopyFile(Stream sourceStm, FileInfo target, IProgressController progressController)1473 public static void CopyFile(Stream sourceStm, FileInfo target, IProgressController progressController) 1474 { 1475 const int bufferSize = 1024 * 1024; // 1MB 1476 byte[] buffer = new byte[bufferSize]; 1477 int reportedProgress = 0, read = 0; 1478 long len = sourceStm.Length; 1479 float flen = len; 1480 1481 using (var targetStm = target.OpenWrite()) { 1482 targetStm.SetLength(sourceStm.Length); 1483 for (long size = 0; size < len; size += read) { 1484 if (progressController != null) { 1485 int progress = (int)((size / flen) * 100); 1486 if (progress != reportedProgress) { 1487 reportedProgress = progress; 1488 progressController.ProgressStep(reportedProgress); 1489 } 1490 } 1491 1492 read = sourceStm.Read(buffer, 0, bufferSize); 1493 targetStm.Write(buffer, 0, read); 1494 } 1495 } 1496 } 1497 LoadResourceStream(string resName)1498 public static Stream LoadResourceStream(string resName) 1499 { 1500 return LoadResourceStream(typeof(GKUtils), resName); 1501 } 1502 LoadResourceStream(Type baseType, string resName)1503 public static Stream LoadResourceStream(Type baseType, string resName) 1504 { 1505 Assembly assembly = baseType.Assembly; 1506 return assembly.GetManifestResourceStream(resName); 1507 } 1508 GetRelativePath(string fromFileName, string toFileName)1509 public static string GetRelativePath(string fromFileName, string toFileName) 1510 { 1511 var fromPath = Path.GetDirectoryName(fromFileName)+ Path.DirectorySeparatorChar; 1512 1513 var fromUri = new Uri(fromPath); 1514 var toUri = new Uri(toFileName); 1515 1516 var relativeUri = fromUri.MakeRelativeUri(toUri); 1517 var relativePath = Uri.UnescapeDataString(relativeUri.ToString()); 1518 1519 return relativePath.Replace('/', Path.DirectorySeparatorChar); 1520 } 1521 1522 #endregion 1523 1524 #region Show information summary 1525 ShowAddressSummary(GDMAddress address, StringList summary)1526 private static void ShowAddressSummary(GDMAddress address, StringList summary) 1527 { 1528 if (address != null && !address.IsEmpty() && summary != null) 1529 { 1530 summary.Add(" " + LangMan.LS(LSID.LSID_Address) + ":"); 1531 1532 string ts = ""; 1533 if (address.AddressCountry != "") 1534 { 1535 ts = ts + address.AddressCountry + ", "; 1536 } 1537 if (address.AddressState != "") 1538 { 1539 ts = ts + address.AddressState + ", "; 1540 } 1541 if (address.AddressCity != "") 1542 { 1543 ts += address.AddressCity; 1544 } 1545 if (ts != "") 1546 { 1547 summary.Add(" " + ts); 1548 } 1549 1550 ts = ""; 1551 if (address.AddressPostalCode != "") 1552 { 1553 ts = ts + address.AddressPostalCode + ", "; 1554 } 1555 if (address.Lines.Text.Trim() != "") 1556 { 1557 ts += address.Lines.Text.Trim(); 1558 } 1559 if (ts != "") 1560 { 1561 summary.Add(" " + ts); 1562 } 1563 1564 int num = address.PhoneNumbers.Count; 1565 for (int i = 0; i < num; i++) { 1566 summary.Add(" " + address.PhoneNumbers[i].StringValue); 1567 } 1568 1569 int num2 = address.EmailAddresses.Count; 1570 for (int i = 0; i < num2; i++) { 1571 summary.Add(" " + address.EmailAddresses[i].StringValue); 1572 } 1573 1574 int num3 = address.WebPages.Count; 1575 for (int i = 0; i < num3; i++) { 1576 summary.Add(" " + address.WebPages[i].StringValue); 1577 } 1578 } 1579 } 1580 ShowDetailCause(GDMCustomEvent evt, StringList summary)1581 private static void ShowDetailCause(GDMCustomEvent evt, StringList summary) 1582 { 1583 string cause = GetEventCause(evt); 1584 if (summary != null && !string.IsNullOrEmpty(cause)) { 1585 summary.Add(" " + cause); 1586 } 1587 } 1588 ShowEventDetailInfo(IBaseContext baseContext, GDMCustomEvent eventDetail, StringList summary)1589 private static void ShowEventDetailInfo(IBaseContext baseContext, GDMCustomEvent eventDetail, StringList summary) 1590 { 1591 if (eventDetail == null) 1592 throw new ArgumentNullException("eventDetail"); 1593 1594 if (summary != null && eventDetail.SourceCitations.Count != 0) { 1595 summary.Add(" " + LangMan.LS(LSID.LSID_RPSources) + " (" + eventDetail.SourceCitations.Count.ToString() + "):"); 1596 1597 int num = eventDetail.SourceCitations.Count; 1598 for (int i = 0; i < num; i++) { 1599 GDMSourceCitation sourCit = eventDetail.SourceCitations[i]; 1600 GDMSourceRecord sourceRec = baseContext.Tree.GetPtrValue<GDMSourceRecord>(sourCit); 1601 if (sourceRec == null) continue; 1602 1603 string nm = "\"" + sourceRec.ShortTitle + "\""; 1604 if (!string.IsNullOrEmpty(sourCit.Page)) { 1605 nm = nm + ", " + sourCit.Page; 1606 } 1607 summary.Add(" " + HyperLink(sourceRec.XRef, nm, 0)); 1608 } 1609 } 1610 } 1611 ShowEvent(GDMTree tree, GDMRecord subj, StringList aToList, GDMRecord aRec, GDMCustomEvent evt)1612 private static void ShowEvent(GDMTree tree, GDMRecord subj, StringList aToList, GDMRecord aRec, GDMCustomEvent evt) 1613 { 1614 if (subj is GDMNoteRecord) { 1615 int num = evt.Notes.Count; 1616 for (int i = 0; i < num; i++) { 1617 if (evt.Notes[i].XRef == subj.XRef) { 1618 ShowLink(tree, subj, aToList, aRec, evt, null); 1619 } 1620 } 1621 } else if (subj is GDMMultimediaRecord) { 1622 int num2 = evt.MultimediaLinks.Count; 1623 for (int i = 0; i < num2; i++) { 1624 if (evt.MultimediaLinks[i].XRef == subj.XRef) { 1625 ShowLink(tree, subj, aToList, aRec, evt, null); 1626 } 1627 } 1628 } else if (subj is GDMSourceRecord) { 1629 int num3 = evt.SourceCitations.Count; 1630 for (int i = 0; i < num3; i++) { 1631 if (evt.SourceCitations[i].XRef == subj.XRef) { 1632 ShowLink(tree, subj, aToList, aRec, evt, evt.SourceCitations[i]); 1633 } 1634 } 1635 } 1636 } 1637 ShowLink(GDMTree tree, GDMRecord aSubject, StringList aToList, GDMRecord aRec, GDMTag aTag, GDMPointer aExt)1638 private static void ShowLink(GDMTree tree, GDMRecord aSubject, StringList aToList, GDMRecord aRec, GDMTag aTag, GDMPointer aExt) 1639 { 1640 string prefix; 1641 if (aSubject is GDMSourceRecord && aExt != null) { 1642 GDMSourceCitation cit = (aExt as GDMSourceCitation); 1643 if (cit != null && !string.IsNullOrEmpty(cit.Page)) { 1644 prefix = cit.Page + ": "; 1645 } else { 1646 prefix = ""; 1647 } 1648 } else { 1649 prefix = ""; 1650 } 1651 1652 string suffix; 1653 if (aTag is GDMCustomEvent) { 1654 suffix = ", " + GetEventName((GDMCustomEvent) aTag).ToLower(); 1655 } else { 1656 suffix = ""; 1657 } 1658 aToList.Add(" " + prefix + GenRecordLink(tree, aRec, true) + suffix); 1659 } 1660 ShowPersonExtInfo(GDMTree tree, GDMIndividualRecord iRec, StringList summary)1661 private static void ShowPersonExtInfo(GDMTree tree, GDMIndividualRecord iRec, StringList summary) 1662 { 1663 /*if (tree == null || iRec == null || summary == null) return; 1664 1665 summary.Add(""); 1666 int num = tree.RecordsCount; 1667 for (int i = 0; i < num; i++) { 1668 GEDCOMRecord rec = tree[i]; 1669 if (rec.RecordType != GEDCOMRecordType.rtIndividual) continue; 1670 1671 GEDCOMIndividualRecord ir = (GEDCOMIndividualRecord)rec; 1672 1673 bool first = true; 1674 for (int k = 0, cnt = ir.Associations.Count; k < cnt; k++) { 1675 GEDCOMAssociation asso = ir.Associations[k]; 1676 1677 if (asso.Individual == iRec) { 1678 if (first) { 1679 summary.Add(LangMan.LS(LSID.LSID_Associations) + ":"); 1680 first = false; 1681 } 1682 summary.Add(" " + HyperLink(ir.XRef, ir.GetNameString(true, false), 0)); 1683 } 1684 } 1685 }*/ 1686 } 1687 ShowPersonNamesakes(GDMTree tree, GDMIndividualRecord iRec, StringList summary)1688 private static void ShowPersonNamesakes(GDMTree tree, GDMIndividualRecord iRec, StringList summary) 1689 { 1690 try { 1691 StringList namesakes = new StringList(); 1692 try { 1693 string st = GetNameString(iRec, true, false); 1694 1695 int num3 = tree.RecordsCount; 1696 for (int i = 0; i < num3; i++) { 1697 GDMRecord rec = tree[i]; 1698 1699 if (rec is GDMIndividualRecord && rec != iRec) { 1700 GDMIndividualRecord relPerson = (GDMIndividualRecord) rec; 1701 1702 string unk = GetNameString(relPerson, true, false); 1703 if (st == unk) { 1704 namesakes.AddObject(unk + GetLifeStr(relPerson), relPerson); 1705 } 1706 } 1707 } 1708 1709 if (namesakes.Count > 0) { 1710 summary.Add(""); 1711 summary.Add(LangMan.LS(LSID.LSID_Namesakes) + ":"); 1712 1713 int num4 = namesakes.Count; 1714 for (int i = 0; i < num4; i++) { 1715 GDMIndividualRecord relPerson = (GDMIndividualRecord)namesakes.GetObject(i); 1716 1717 summary.Add(" " + HyperLink(relPerson.XRef, namesakes[i], 0)); 1718 } 1719 } 1720 } 1721 finally { 1722 namesakes.Dispose(); 1723 } 1724 } catch (Exception ex) { 1725 Logger.WriteError("GKUtils.ShowPersonNamesakes()", ex); 1726 } 1727 } 1728 ShowSubjectLinks(GDMTree tree, GDMRecord aInRecord, GDMRecord subject, StringList aToList)1729 private static void ShowSubjectLinks(GDMTree tree, GDMRecord aInRecord, GDMRecord subject, StringList aToList) 1730 { 1731 try { 1732 int num; 1733 1734 if (subject is GDMNoteRecord && aInRecord.HasNotes) { 1735 num = aInRecord.Notes.Count; 1736 for (int i = 0; i < num; i++) { 1737 if (aInRecord.Notes[i].XRef == subject.XRef) { 1738 ShowLink(tree, subject, aToList, aInRecord, null, null); 1739 } 1740 } 1741 } else if (subject is GDMMultimediaRecord && aInRecord.HasMultimediaLinks) { 1742 num = aInRecord.MultimediaLinks.Count; 1743 for (int i = 0; i < num; i++) { 1744 if (aInRecord.MultimediaLinks[i].XRef == subject.XRef) { 1745 ShowLink(tree, subject, aToList, aInRecord, null, null); 1746 } 1747 } 1748 } else if (subject is GDMSourceRecord && aInRecord.HasSourceCitations) { 1749 num = aInRecord.SourceCitations.Count; 1750 for (int i = 0; i < num; i++) { 1751 var sourCit = aInRecord.SourceCitations[i]; 1752 if (sourCit.XRef == subject.XRef) { 1753 ShowLink(tree, subject, aToList, aInRecord, null, sourCit); 1754 } 1755 } 1756 } 1757 1758 var evsRec = aInRecord as GDMRecordWithEvents; 1759 if (evsRec != null && evsRec.HasEvents) { 1760 num = evsRec.Events.Count; 1761 for (int i = 0; i < num; i++) { 1762 ShowEvent(tree, subject, aToList, evsRec, evsRec.Events[i]); 1763 } 1764 } 1765 } catch (Exception ex) { 1766 Logger.WriteError("GKUtils.ShowSubjectLinks()", ex); 1767 } 1768 } 1769 SearchRecordLinks(List<GDMObject> linksList, GDMRecord inRecord, GDMRecord searchRec)1770 public static void SearchRecordLinks(List<GDMObject> linksList, GDMRecord inRecord, GDMRecord searchRec) 1771 { 1772 try { 1773 int num; 1774 switch (searchRec.RecordType) { 1775 case GDMRecordType.rtNote: 1776 num = inRecord.Notes.Count; 1777 for (int i = 0; i < num; i++) { 1778 var notes = inRecord.Notes[i]; 1779 if (notes.XRef == searchRec.XRef) { 1780 linksList.Add(notes); 1781 } 1782 } 1783 break; 1784 1785 case GDMRecordType.rtMultimedia: 1786 num = inRecord.MultimediaLinks.Count; 1787 for (int i = 0; i < num; i++) { 1788 var mmLink = inRecord.MultimediaLinks[i]; 1789 if (mmLink.XRef == searchRec.XRef) { 1790 linksList.Add(mmLink); 1791 } 1792 } 1793 break; 1794 1795 case GDMRecordType.rtSource: 1796 num = inRecord.SourceCitations.Count; 1797 for (int i = 0; i < num; i++) { 1798 var sourCit = inRecord.SourceCitations[i]; 1799 if (sourCit.XRef == searchRec.XRef) { 1800 linksList.Add(sourCit); 1801 } 1802 } 1803 break; 1804 } 1805 1806 /*var recordWithEvents = aInRecord as GEDCOMRecordWithEvents; 1807 if (recordWithEvents != null) { 1808 GEDCOMRecordWithEvents evsRec = recordWithEvents; 1809 1810 num = evsRec.Events.Count; 1811 for (int i = 0; i < num; i++) { 1812 ShowEvent(subject, linksList, evsRec, evsRec.Events[i]); 1813 } 1814 }*/ 1815 } catch (Exception ex) { 1816 Logger.WriteError("GKUtils.SearchRecordLinks()", ex); 1817 } 1818 } 1819 SearchRecordLinks(List<GDMObject> linksList, GDMTree tree, GDMRecord searchRec)1820 public static void SearchRecordLinks(List<GDMObject> linksList, GDMTree tree, GDMRecord searchRec) 1821 { 1822 int num = tree.RecordsCount; 1823 for (int i = 0; i < num; i++) { 1824 SearchRecordLinks(linksList, tree[i], searchRec); 1825 } 1826 } 1827 SearchPortraits(GDMTree tree, GDMMultimediaRecord mmRec)1828 public static StringList SearchPortraits(GDMTree tree, GDMMultimediaRecord mmRec) 1829 { 1830 var result = new StringList(); 1831 1832 int num = tree.RecordsCount; 1833 for (int i = 0; i < num; i++) { 1834 var rec = tree[i]; 1835 if (rec.RecordType == GDMRecordType.rtIndividual) { 1836 var iRec = rec as GDMIndividualRecord; 1837 1838 num = iRec.MultimediaLinks.Count; 1839 for (int k = 0; i < num; i++) { 1840 var mmLink = iRec.MultimediaLinks[k]; 1841 if (mmLink.XRef == mmRec.XRef && mmLink.IsPrimary) { 1842 string indiName = GKUtils.GetNameString(iRec, true, false); 1843 ExtRect region = mmLink.CutoutPosition.Value; 1844 result.AddObject(indiName, region); 1845 } 1846 } 1847 } 1848 } 1849 1850 return result; 1851 } 1852 RecListMediaRefresh(IBaseContext baseContext, GDMRecord record, StringList summary)1853 private static void RecListMediaRefresh(IBaseContext baseContext, GDMRecord record, StringList summary) 1854 { 1855 if (record == null || summary == null) return; 1856 1857 try { 1858 if (record.HasMultimediaLinks) { 1859 summary.Add(""); 1860 summary.Add(LangMan.LS(LSID.LSID_RPMultimedia) + " (" + record.MultimediaLinks.Count.ToString() + "):"); 1861 1862 int num = record.MultimediaLinks.Count; 1863 for (int i = 0; i < num; i++) { 1864 GDMMultimediaLink mmLink = record.MultimediaLinks[i]; 1865 GDMMultimediaRecord mmRec = baseContext.Tree.GetPtrValue<GDMMultimediaRecord>(mmLink); 1866 if (mmRec == null || mmRec.FileReferences.Count == 0) continue; 1867 1868 string st = mmRec.FileReferences[0].Title; 1869 summary.Add(" " + HyperLink(mmRec.XRef, st, 0) + " (" + 1870 HyperLink("view_" + mmRec.XRef, LangMan.LS(LSID.LSID_MediaView), 0) + ")"); 1871 } 1872 } 1873 } catch (Exception ex) { 1874 Logger.WriteError("GKUtils.RecListMediaRefresh()", ex); 1875 } 1876 } 1877 RecListNotesRefresh(IBaseContext baseContext, GDMRecord record, StringList summary)1878 private static void RecListNotesRefresh(IBaseContext baseContext, GDMRecord record, StringList summary) 1879 { 1880 if (record == null || summary == null) return; 1881 1882 try { 1883 if (record.HasNotes) { 1884 summary.Add(""); 1885 summary.Add(LangMan.LS(LSID.LSID_RPNotes) + " (" + record.Notes.Count.ToString() + "):"); 1886 1887 int num = record.Notes.Count; 1888 for (int i = 0; i < num; i++) { 1889 if (i > 0) { 1890 summary.Add(""); 1891 } 1892 1893 GDMLines noteLines = baseContext.Tree.GetNoteLines(record.Notes[i]); 1894 int num2 = noteLines.Count; 1895 for (int k = 0; k < num2; k++) { 1896 summary.Add(noteLines[k]); 1897 } 1898 } 1899 } 1900 } catch (Exception ex) { 1901 Logger.WriteError("GKUtils.RecListNotesRefresh()", ex); 1902 } 1903 } 1904 RecListSourcesRefresh(IBaseContext baseContext, GDMRecord record, StringList summary)1905 private static void RecListSourcesRefresh(IBaseContext baseContext, GDMRecord record, StringList summary) 1906 { 1907 if (record == null || summary == null) return; 1908 1909 try { 1910 if (record.HasSourceCitations) { 1911 summary.Add(""); 1912 summary.Add(LangMan.LS(LSID.LSID_RPSources) + " (" + record.SourceCitations.Count.ToString() + "):"); 1913 1914 int num = record.SourceCitations.Count; 1915 for (int i = 0; i < num; i++) { 1916 GDMSourceCitation sourCit = record.SourceCitations[i]; 1917 GDMSourceRecord sourceRec = baseContext.Tree.GetPtrValue<GDMSourceRecord>(sourCit); 1918 if (sourceRec == null) continue; 1919 1920 string nm = "\"" + sourceRec.ShortTitle + "\""; 1921 1922 if (sourCit.Page != "") { 1923 nm = nm + ", " + sourCit.Page; 1924 } 1925 1926 summary.Add(" " + HyperLink(sourceRec.XRef, nm, 0)); 1927 } 1928 } 1929 } catch (Exception ex) { 1930 Logger.WriteError("GKUtils.RecListSourcesRefresh()", ex); 1931 } 1932 } 1933 RecListAssociationsRefresh(IBaseContext baseContext, GDMIndividualRecord record, StringList summary)1934 private static void RecListAssociationsRefresh(IBaseContext baseContext, GDMIndividualRecord record, StringList summary) 1935 { 1936 if (record == null || summary == null) return; 1937 1938 try { 1939 if (record.HasAssociations) { 1940 summary.Add(""); 1941 summary.Add(LangMan.LS(LSID.LSID_Associations) + ":"); 1942 1943 int num = record.Associations.Count; 1944 for (int i = 0; i < num; i++) { 1945 GDMAssociation ast = record.Associations[i]; 1946 var relIndi = baseContext.Tree.GetPtrValue(ast); 1947 1948 string nm = ((relIndi == null) ? string.Empty : GetNameString(relIndi, true, false)); 1949 string xref = ((relIndi == null) ? string.Empty : relIndi.XRef); 1950 1951 summary.Add(" " + ast.Relation + " " + HyperLink(xref, nm, 0)); 1952 } 1953 } 1954 } catch (Exception ex) { 1955 Logger.WriteError("GKUtils.RecListAssociationsRefresh()", ex); 1956 } 1957 } 1958 RecListIndividualEventsRefresh(IBaseContext baseContext, GDMIndividualRecord record, StringList summary)1959 private static void RecListIndividualEventsRefresh(IBaseContext baseContext, GDMIndividualRecord record, StringList summary) 1960 { 1961 if (record == null || summary == null) return; 1962 1963 try { 1964 if (record.HasEvents) { 1965 summary.Add(""); 1966 summary.Add(LangMan.LS(LSID.LSID_Events) + ":"); 1967 1968 int num = record.Events.Count; 1969 for (int i = 0; i < num; i++) { 1970 summary.Add(""); 1971 1972 GDMCustomEvent evt = record.Events[i]; 1973 string st = GetEventName(evt); 1974 1975 string sv = ""; 1976 if (evt.StringValue != "") { 1977 sv = evt.StringValue + ", "; 1978 } 1979 summary.Add(" " + st + ": " + sv + GetEventDesc(baseContext.Tree, evt)); 1980 1981 ShowDetailCause(evt, summary); 1982 if (evt.HasAddress) { 1983 ShowAddressSummary(evt.Address, summary); 1984 } 1985 ShowEventDetailInfo(baseContext, evt, summary); 1986 } 1987 } 1988 } catch (Exception ex) { 1989 Logger.WriteError("GKUtils.RecListIndividualEventsRefresh()", ex); 1990 } 1991 } 1992 RecListFamilyEventsRefresh(IBaseContext baseContext, GDMFamilyRecord record, StringList summary)1993 private static void RecListFamilyEventsRefresh(IBaseContext baseContext, GDMFamilyRecord record, StringList summary) 1994 { 1995 if (record == null || summary == null) return; 1996 1997 try { 1998 if (record.HasEvents) { 1999 summary.Add(""); 2000 summary.Add(LangMan.LS(LSID.LSID_Events) + ":"); 2001 2002 int num = record.Events.Count; 2003 for (int i = 0; i < num; i++) { 2004 summary.Add(""); 2005 2006 GDMFamilyEvent evt = (GDMFamilyEvent)record.Events[i]; 2007 2008 string st = GetEventName(evt); 2009 summary.Add(" " + st + ": " + GetEventDesc(baseContext.Tree, evt)); 2010 2011 ShowDetailCause(evt, summary); 2012 ShowEventDetailInfo(baseContext, evt, summary); 2013 } 2014 } 2015 } catch (Exception ex) { 2016 Logger.WriteError("GKUtils.RecListFamilyEventsRefresh()", ex); 2017 } 2018 } 2019 RecListGroupsRefresh(IBaseContext baseContext, GDMIndividualRecord record, StringList summary)2020 private static void RecListGroupsRefresh(IBaseContext baseContext, GDMIndividualRecord record, StringList summary) 2021 { 2022 if (record == null || summary == null) return; 2023 2024 try { 2025 if (record.HasGroups) { 2026 summary.Add(""); 2027 summary.Add(LangMan.LS(LSID.LSID_RPGroups) + ":"); 2028 2029 int num = record.Groups.Count; 2030 for (int i = 0; i < num; i++) { 2031 GDMPointer ptr = record.Groups[i]; 2032 GDMGroupRecord grp = baseContext.Tree.GetPtrValue<GDMGroupRecord>(ptr); 2033 if (grp == null) continue; 2034 2035 summary.Add(" " + HyperLink(grp.XRef, grp.GroupName, 0)); 2036 } 2037 } 2038 } catch (Exception ex) { 2039 Logger.WriteError("GKUtils.RecListGroupsRefresh()", ex); 2040 } 2041 } 2042 2043 // 2044 ShowFamilyInfo(IBaseContext baseContext, GDMFamilyRecord familyRec, StringList summary)2045 public static void ShowFamilyInfo(IBaseContext baseContext, GDMFamilyRecord familyRec, StringList summary) 2046 { 2047 if (summary == null) return; 2048 2049 try { 2050 summary.BeginUpdate(); 2051 try { 2052 summary.Clear(); 2053 if (familyRec != null) { 2054 summary.Add(""); 2055 2056 GDMIndividualRecord spRec = baseContext.Tree.GetPtrValue(familyRec.Husband); 2057 string st = ((spRec == null) ? LangMan.LS(LSID.LSID_UnkMale) : HyperLink(spRec.XRef, GetNameString(spRec, true, false), 0)); 2058 summary.Add(LangMan.LS(LSID.LSID_Husband) + ": " + st + GetLifeStr(spRec)); 2059 2060 spRec = baseContext.Tree.GetPtrValue(familyRec.Wife); 2061 st = ((spRec == null) ? LangMan.LS(LSID.LSID_UnkFemale) : HyperLink(spRec.XRef, GetNameString(spRec, true, false), 0)); 2062 summary.Add(LangMan.LS(LSID.LSID_Wife) + ": " + st + GetLifeStr(spRec)); 2063 2064 summary.Add(""); 2065 if (familyRec.Children.Count != 0) { 2066 summary.Add(LangMan.LS(LSID.LSID_Childs) + ":"); 2067 } 2068 2069 int num = familyRec.Children.Count; 2070 for (int i = 0; i < num; i++) { 2071 var child = baseContext.Tree.GetPtrValue(familyRec.Children[i]); 2072 summary.Add(" " + HyperLink(child.XRef, GetNameString(child, true, false), 0) + GetLifeStr(child)); 2073 } 2074 summary.Add(""); 2075 2076 RecListFamilyEventsRefresh(baseContext, familyRec, summary); 2077 RecListNotesRefresh(baseContext, familyRec, summary); 2078 RecListMediaRefresh(baseContext, familyRec, summary); 2079 RecListSourcesRefresh(baseContext, familyRec, summary); 2080 } 2081 } finally { 2082 summary.EndUpdate(); 2083 } 2084 } catch (Exception ex) { 2085 Logger.WriteError("GKUtils.ShowFamilyInfo()" , ex); 2086 } 2087 } 2088 ShowGroupInfo(IBaseContext baseContext, GDMGroupRecord groupRec, StringList summary)2089 public static void ShowGroupInfo(IBaseContext baseContext, GDMGroupRecord groupRec, StringList summary) 2090 { 2091 if (summary == null) return; 2092 2093 try { 2094 StringList mbrList = new StringList(); 2095 summary.BeginUpdate(); 2096 try { 2097 summary.Clear(); 2098 if (groupRec != null) { 2099 summary.Add(""); 2100 summary.Add("[u][b][size=+1]" + groupRec.GroupName + "[/size][/b][/u]"); 2101 summary.Add(""); 2102 summary.Add(LangMan.LS(LSID.LSID_Members) + " (" + groupRec.Members.Count.ToString() + "):"); 2103 2104 int num = groupRec.Members.Count; 2105 for (int i = 0; i < num; i++) { 2106 GDMPointer ptr = groupRec.Members[i]; 2107 var member = baseContext.Tree.GetPtrValue<GDMIndividualRecord>(ptr); 2108 2109 mbrList.AddObject(GetNameString(member, true, false), member); 2110 } 2111 mbrList.Sort(); 2112 2113 int num2 = mbrList.Count; 2114 for (int i = 0; i < num2; i++) { 2115 GDMIndividualRecord member = (GDMIndividualRecord)mbrList.GetObject(i); 2116 2117 summary.Add(" " + HyperLink(member.XRef, mbrList[i], i + 1)); 2118 } 2119 2120 RecListNotesRefresh(baseContext, groupRec, summary); 2121 RecListMediaRefresh(baseContext, groupRec, summary); 2122 } 2123 } finally { 2124 summary.EndUpdate(); 2125 mbrList.Dispose(); 2126 } 2127 } catch (Exception ex) { 2128 Logger.WriteError("GKUtils.ShowGroupInfo()", ex); 2129 } 2130 } 2131 ShowMultimediaInfo(IBaseContext baseContext, GDMMultimediaRecord mediaRec, StringList summary)2132 public static void ShowMultimediaInfo(IBaseContext baseContext, GDMMultimediaRecord mediaRec, StringList summary) 2133 { 2134 if (summary == null) return; 2135 2136 try { 2137 summary.BeginUpdate(); 2138 try { 2139 summary.Clear(); 2140 if (mediaRec != null) { 2141 GDMFileReferenceWithTitle fileRef = mediaRec.FileReferences[0]; 2142 string mediaTitle = (fileRef == null) ? LangMan.LS(LSID.LSID_Unknown) : fileRef.Title; 2143 2144 summary.Add(""); 2145 summary.Add("[u][b][size=+1]" + mediaTitle + "[/size][/b][/u]"); 2146 summary.Add(""); 2147 if (fileRef != null) { 2148 summary.Add("[ " + HyperLink("view_" + mediaRec.XRef, LangMan.LS(LSID.LSID_View), 0) + " ]"); 2149 } 2150 summary.Add(""); 2151 summary.Add(LangMan.LS(LSID.LSID_Links) + ":"); 2152 2153 GDMTree tree = baseContext.Tree; 2154 int num = tree.RecordsCount; 2155 for (int i = 0; i < num; i++) { 2156 ShowSubjectLinks(tree, tree[i], mediaRec, summary); 2157 } 2158 2159 RecListNotesRefresh(baseContext, mediaRec, summary); 2160 RecListSourcesRefresh(baseContext, mediaRec, summary); 2161 } 2162 } finally { 2163 summary.EndUpdate(); 2164 } 2165 } catch (Exception ex) { 2166 Logger.WriteError("GKUtils.ShowMultimediaInfo()", ex); 2167 } 2168 } 2169 ShowNoteInfo(IBaseContext baseContext, GDMNoteRecord noteRec, StringList summary)2170 public static void ShowNoteInfo(IBaseContext baseContext, GDMNoteRecord noteRec, StringList summary) 2171 { 2172 if (summary == null) return; 2173 2174 try { 2175 summary.BeginUpdate(); 2176 try { 2177 summary.Clear(); 2178 if (noteRec != null) { 2179 summary.Add(""); 2180 summary.AddStrings(noteRec.Lines.ToArray()); 2181 summary.Add(""); 2182 summary.Add(LangMan.LS(LSID.LSID_Links) + ":"); 2183 2184 GDMTree tree = baseContext.Tree; 2185 int num = tree.RecordsCount; 2186 for (int i = 0; i < num; i++) { 2187 ShowSubjectLinks(tree, tree[i], noteRec, summary); 2188 } 2189 } 2190 } finally { 2191 summary.EndUpdate(); 2192 } 2193 } catch (Exception ex) { 2194 Logger.WriteError("GKUtils.ShowNoteInfo()", ex); 2195 } 2196 } 2197 ShowPersonInfo(IBaseContext baseContext, GDMIndividualRecord iRec, StringList summary)2198 public static void ShowPersonInfo(IBaseContext baseContext, GDMIndividualRecord iRec, StringList summary) 2199 { 2200 if (summary == null) return; 2201 2202 try { 2203 summary.BeginUpdate(); 2204 summary.Clear(); 2205 try { 2206 if (iRec != null) { 2207 GDMTree tree = baseContext.Tree; 2208 2209 summary.Add(""); 2210 summary.Add("[u][b][size=+1]" + GetNameString(iRec, true, true) + "[/size][/u][/b]"); 2211 summary.Add(LangMan.LS(LSID.LSID_Sex) + ": " + SexStr(iRec.Sex)); 2212 try { 2213 GDMIndividualRecord father, mother; 2214 tree.GetParents(iRec, out father, out mother); 2215 2216 if (father != null || mother != null) { 2217 summary.Add(""); 2218 summary.Add(LangMan.LS(LSID.LSID_Parents) + ":"); 2219 2220 string st; 2221 2222 st = (father == null) ? LangMan.LS(LSID.LSID_UnkMale) : HyperLink(father.XRef, GetNameString(father, true, false), 0); 2223 summary.Add(" " + LangMan.LS(LSID.LSID_Father) + ": " + st + GetLifeStr(father)); 2224 2225 st = (mother == null) ? LangMan.LS(LSID.LSID_UnkFemale) : HyperLink(mother.XRef, GetNameString(mother, true, false), 0); 2226 summary.Add(" " + LangMan.LS(LSID.LSID_Mother) + ": " + st + GetLifeStr(mother)); 2227 } 2228 } catch (Exception ex) { 2229 Logger.WriteError("GKUtils.ShowPersonInfo().Parents()", ex); 2230 } 2231 2232 try { 2233 int num = iRec.SpouseToFamilyLinks.Count; 2234 for (int i = 0; i < num; i++) { 2235 GDMFamilyRecord family = tree.GetPtrValue(iRec.SpouseToFamilyLinks[i]); 2236 if (family == null) continue; 2237 if (!baseContext.IsRecordAccess(family.Restriction)) continue; 2238 2239 string st; 2240 GDMIndividualRecord spRec; 2241 string unk; 2242 if (iRec.Sex == GDMSex.svMale) { 2243 spRec = tree.GetPtrValue(family.Wife); 2244 st = LangMan.LS(LSID.LSID_Wife) + ": "; 2245 unk = LangMan.LS(LSID.LSID_UnkFemale); 2246 } else { 2247 spRec = tree.GetPtrValue(family.Husband); 2248 st = LangMan.LS(LSID.LSID_Husband) + ": "; 2249 unk = LangMan.LS(LSID.LSID_UnkMale); 2250 } 2251 string marr = GetMarriageDateStr(family, GlobalOptions.Instance.DefDateFormat); 2252 if (marr != "") { 2253 marr = LangMan.LS(LSID.LSID_LMarriage) + " " + marr; 2254 } else { 2255 marr = LangMan.LS(LSID.LSID_LFamily); 2256 } 2257 2258 summary.Add(""); 2259 if (spRec != null) { 2260 st = st + HyperLink(spRec.XRef, GetNameString(spRec, true, false), 0) + " (" + HyperLink(family.XRef, marr, 0) + ")"; 2261 } else { 2262 st = st + unk + " (" + HyperLink(family.XRef, marr, 0) + ")"; 2263 } 2264 summary.Add(st); 2265 2266 int chNum = family.Children.Count; 2267 if (chNum != 0) { 2268 summary.Add(""); 2269 summary.Add(LangMan.LS(LSID.LSID_Childs) + ":"); 2270 2271 for (int k = 0; k < chNum; k++) { 2272 GDMIndividualRecord child = tree.GetPtrValue(family.Children[k]); 2273 if (child == null) continue; 2274 2275 summary.Add(" " + HyperLink(child.XRef, GetNameString(child, true, false), 0) + GetLifeStr(child)); 2276 } 2277 } 2278 } 2279 } catch (Exception ex) { 2280 Logger.WriteError("GKUtils.ShowPersonInfo().Families()", ex); 2281 } 2282 2283 RecListIndividualEventsRefresh(baseContext, iRec, summary); 2284 RecListNotesRefresh(baseContext, iRec, summary); 2285 RecListMediaRefresh(baseContext, iRec, summary); 2286 RecListSourcesRefresh(baseContext, iRec, summary); 2287 RecListAssociationsRefresh(baseContext, iRec, summary); 2288 RecListGroupsRefresh(baseContext, iRec, summary); 2289 2290 ShowPersonNamesakes(tree, iRec, summary); 2291 ShowPersonExtInfo(tree, iRec, summary); 2292 } 2293 } finally { 2294 summary.EndUpdate(); 2295 } 2296 } catch (Exception ex) { 2297 Logger.WriteError("GKUtils.ShowPersonInfo()", ex); 2298 } 2299 } 2300 ShowSourceInfo(IBaseContext baseContext, GDMSourceRecord sourceRec, StringList summary)2301 public static void ShowSourceInfo(IBaseContext baseContext, GDMSourceRecord sourceRec, StringList summary) 2302 { 2303 if (summary == null) return; 2304 2305 try { 2306 summary.BeginUpdate(); 2307 StringList linkList = new StringList(); 2308 try { 2309 summary.Clear(); 2310 if (sourceRec != null) { 2311 summary.Add(""); 2312 summary.Add("[u][b][size=+1]" + sourceRec.ShortTitle + "[/size][/b][/u]"); 2313 summary.Add(""); 2314 summary.AddMultiline(LangMan.LS(LSID.LSID_Author) + ": " + sourceRec.Originator.Lines.Text.Trim()); 2315 summary.AddMultiline(LangMan.LS(LSID.LSID_Title) + ": \"" + sourceRec.Title.Lines.Text.Trim() + "\""); 2316 summary.AddMultiline(LangMan.LS(LSID.LSID_Publication) + ": \"" + sourceRec.Publication.Lines.Text.Trim() + "\""); 2317 summary.AddMultiline(LangMan.LS(LSID.LSID_Text) + ": \"" + sourceRec.Text.Lines.Text.Trim() + "\""); 2318 2319 if (sourceRec.RepositoryCitations.Count > 0) { 2320 summary.Add(""); 2321 summary.Add(LangMan.LS(LSID.LSID_RPRepositories) + ":"); 2322 2323 int num = sourceRec.RepositoryCitations.Count; 2324 for (int i = 0; i < num; i++) { 2325 GDMRepositoryRecord rep = baseContext.Tree.GetPtrValue<GDMRepositoryRecord>(sourceRec.RepositoryCitations[i]); 2326 2327 summary.Add(" " + HyperLink(rep.XRef, rep.RepositoryName, 0)); 2328 } 2329 } 2330 2331 summary.Add(""); 2332 summary.Add(LangMan.LS(LSID.LSID_Links) + ":"); 2333 2334 GDMTree tree = baseContext.Tree; 2335 2336 int num2 = tree.RecordsCount; 2337 for (int j = 0; j < num2; j++) { 2338 ShowSubjectLinks(tree, tree[j], sourceRec, linkList); 2339 } 2340 2341 linkList.Sort(); 2342 2343 int num3 = linkList.Count; 2344 for (int j = 0; j < num3; j++) { 2345 summary.Add(linkList[j]); 2346 } 2347 2348 RecListNotesRefresh(baseContext, sourceRec, summary); 2349 RecListMediaRefresh(baseContext, sourceRec, summary); 2350 } 2351 } finally { 2352 linkList.Dispose(); 2353 summary.EndUpdate(); 2354 } 2355 } catch (Exception ex) { 2356 Logger.WriteError("GKUtils.ShowSourceInfo()", ex); 2357 } 2358 } 2359 ShowRepositoryInfo(IBaseContext baseContext, GDMRepositoryRecord repositoryRec, StringList summary)2360 public static void ShowRepositoryInfo(IBaseContext baseContext, GDMRepositoryRecord repositoryRec, StringList summary) 2361 { 2362 if (summary == null) return; 2363 2364 try { 2365 summary.BeginUpdate(); 2366 try { 2367 summary.Clear(); 2368 if (repositoryRec != null) { 2369 summary.Add(""); 2370 summary.Add("[u][b][size=+1]" + repositoryRec.RepositoryName.Trim() + "[/size][/b][/u]"); 2371 summary.Add(""); 2372 2373 ShowAddressSummary(repositoryRec.Address, summary); 2374 2375 summary.Add(""); 2376 summary.Add(LangMan.LS(LSID.LSID_RPSources) + ":"); 2377 2378 var sortedSources = new List<Tuple<string, string>>(); 2379 GDMTree tree = baseContext.Tree; 2380 int num = tree.RecordsCount; 2381 for (int i = 0; i < num; i++) { 2382 GDMRecord rec = tree[i]; 2383 2384 if (rec.RecordType == GDMRecordType.rtSource) { 2385 GDMSourceRecord srcRec = (GDMSourceRecord) rec; 2386 2387 int num2 = srcRec.RepositoryCitations.Count; 2388 for (int j = 0; j < num2; j++) { 2389 if (srcRec.RepositoryCitations[j].XRef == repositoryRec.XRef) { 2390 sortedSources.Add(GenRecordLinkTuple(baseContext.Tree, srcRec, false)); 2391 } 2392 } 2393 } 2394 } 2395 sortedSources.Sort(); 2396 foreach (var tpl in sortedSources) { 2397 summary.Add(" " + tpl.Item2); 2398 } 2399 2400 RecListNotesRefresh(baseContext, repositoryRec, summary); 2401 } 2402 } finally { 2403 summary.EndUpdate(); 2404 } 2405 } catch (Exception ex) { 2406 Logger.WriteError("GKUtils.ShowRepositoryInfo()", ex); 2407 } 2408 } 2409 ShowResearchInfo(IBaseContext baseContext, GDMResearchRecord researchRec, StringList summary)2410 public static void ShowResearchInfo(IBaseContext baseContext, GDMResearchRecord researchRec, StringList summary) 2411 { 2412 if (summary == null) return; 2413 2414 try { 2415 summary.BeginUpdate(); 2416 try { 2417 summary.Clear(); 2418 if (researchRec != null) { 2419 summary.Add(""); 2420 summary.Add(LangMan.LS(LSID.LSID_Title) + ": [u][b][size=+1]\"" + researchRec.ResearchName.Trim() + "\"[/size][/b][/u]"); 2421 summary.Add(""); 2422 summary.Add(LangMan.LS(LSID.LSID_Priority) + ": " + LangMan.LS(GKData.PriorityNames[(int)researchRec.Priority])); 2423 summary.Add(LangMan.LS(LSID.LSID_Status) + ": " + LangMan.LS(GKData.StatusNames[(int)researchRec.Status]) + " (" + researchRec.Percent.ToString() + "%)"); 2424 summary.Add(LangMan.LS(LSID.LSID_StartDate) + ": " + researchRec.StartDate.GetDisplayString(GlobalOptions.Instance.DefDateFormat)); 2425 summary.Add(LangMan.LS(LSID.LSID_StopDate) + ": " + researchRec.StopDate.GetDisplayString(GlobalOptions.Instance.DefDateFormat)); 2426 2427 if (researchRec.Tasks.Count > 0) { 2428 summary.Add(""); 2429 summary.Add(LangMan.LS(LSID.LSID_RPTasks) + ":"); 2430 2431 int num = researchRec.Tasks.Count; 2432 for (int i = 0; i < num; i++) { 2433 var taskRec = baseContext.Tree.GetPtrValue<GDMTaskRecord>(researchRec.Tasks[i]); 2434 summary.Add(" " + GenRecordLink(baseContext.Tree, taskRec, false)); 2435 } 2436 } 2437 2438 if (researchRec.Communications.Count > 0) { 2439 summary.Add(""); 2440 summary.Add(LangMan.LS(LSID.LSID_RPCommunications) + ":"); 2441 2442 int num2 = researchRec.Communications.Count; 2443 for (int i = 0; i < num2; i++) { 2444 var corrRec = baseContext.Tree.GetPtrValue<GDMCommunicationRecord>(researchRec.Communications[i]); 2445 summary.Add(" " + GenRecordLink(baseContext.Tree, corrRec, false)); 2446 } 2447 } 2448 2449 if (researchRec.Groups.Count != 0) { 2450 summary.Add(""); 2451 summary.Add(LangMan.LS(LSID.LSID_RPGroups) + ":"); 2452 2453 int num3 = researchRec.Groups.Count; 2454 for (int i = 0; i < num3; i++) { 2455 var grp = baseContext.Tree.GetPtrValue<GDMGroupRecord>(researchRec.Groups[i]); 2456 summary.Add(" " + HyperLink(grp.XRef, grp.GroupName, 0)); 2457 } 2458 } 2459 2460 RecListNotesRefresh(baseContext, researchRec, summary); 2461 } 2462 } finally { 2463 summary.EndUpdate(); 2464 } 2465 } catch (Exception ex) { 2466 Logger.WriteError("GKUtils.ShowResearchInfo()", ex); 2467 } 2468 } 2469 ShowTaskInfo(IBaseContext baseContext, GDMTaskRecord taskRec, StringList summary)2470 public static void ShowTaskInfo(IBaseContext baseContext, GDMTaskRecord taskRec, StringList summary) 2471 { 2472 if (summary == null) return; 2473 2474 try { 2475 summary.BeginUpdate(); 2476 try { 2477 summary.Clear(); 2478 if (taskRec != null) { 2479 summary.Add(""); 2480 summary.Add(LangMan.LS(LSID.LSID_Goal) + ": [u][b][size=+1]" + GetTaskGoalStr(baseContext.Tree, taskRec) + "[/size][/b][/u]"); 2481 summary.Add(""); 2482 summary.Add(LangMan.LS(LSID.LSID_Priority) + ": " + LangMan.LS(GKData.PriorityNames[(int)taskRec.Priority])); 2483 summary.Add(LangMan.LS(LSID.LSID_StartDate) + ": " + taskRec.StartDate.GetDisplayString(GlobalOptions.Instance.DefDateFormat)); 2484 summary.Add(LangMan.LS(LSID.LSID_StopDate) + ": " + taskRec.StopDate.GetDisplayString(GlobalOptions.Instance.DefDateFormat)); 2485 2486 RecListNotesRefresh(baseContext, taskRec, summary); 2487 } 2488 } finally { 2489 summary.EndUpdate(); 2490 } 2491 } catch (Exception ex) { 2492 Logger.WriteError("GKUtils.ShowTaskInfo()", ex); 2493 } 2494 } 2495 ShowCommunicationInfo(IBaseContext baseContext, GDMCommunicationRecord commRec, StringList summary)2496 public static void ShowCommunicationInfo(IBaseContext baseContext, GDMCommunicationRecord commRec, StringList summary) 2497 { 2498 if (summary == null) return; 2499 2500 try { 2501 summary.BeginUpdate(); 2502 try { 2503 summary.Clear(); 2504 if (commRec != null) { 2505 GDMTree tree = baseContext.Tree; 2506 2507 summary.Add(""); 2508 summary.Add(LangMan.LS(LSID.LSID_Theme) + ": [u][b][size=+1]\"" + commRec.CommName.Trim() + "\"[/size][/b][/u]"); 2509 summary.Add(""); 2510 summary.Add(LangMan.LS(LSID.LSID_Corresponder) + ": " + GetCorresponderStr(tree, commRec, true)); 2511 summary.Add(LangMan.LS(LSID.LSID_Type) + ": " + LangMan.LS(GKData.CommunicationNames[(int)commRec.CommunicationType])); 2512 summary.Add(LangMan.LS(LSID.LSID_Date) + ": " + commRec.Date.GetDisplayString(GlobalOptions.Instance.DefDateFormat)); 2513 2514 RecListNotesRefresh(baseContext, commRec, summary); 2515 RecListMediaRefresh(baseContext, commRec, summary); 2516 } 2517 } finally { 2518 summary.EndUpdate(); 2519 } 2520 } catch (Exception ex) { 2521 Logger.WriteError("GKUtils.ShowCommunicationInfo()", ex); 2522 } 2523 } 2524 ShowLocationInfo(IBaseContext baseContext, GDMLocationRecord locRec, StringList summary)2525 public static void ShowLocationInfo(IBaseContext baseContext, GDMLocationRecord locRec, StringList summary) 2526 { 2527 if (summary == null) return; 2528 2529 try { 2530 summary.BeginUpdate(); 2531 StringList linkList = null; 2532 try { 2533 summary.Clear(); 2534 if (locRec != null) { 2535 summary.Add(""); 2536 summary.Add("[u][b][size=+1]" + locRec.LocationName.Trim() + "[/size][/b][/u]"); 2537 summary.Add(""); 2538 summary.Add(LangMan.LS(LSID.LSID_Latitude) + ": " + locRec.Map.Lati); 2539 summary.Add(LangMan.LS(LSID.LSID_Longitude) + ": " + locRec.Map.Long); 2540 2541 GDMTree tree = baseContext.Tree; 2542 2543 linkList = GetLocationLinks(tree, locRec); 2544 2545 if (linkList.Count > 0) { 2546 linkList.Sort(); 2547 2548 summary.Add(""); 2549 summary.Add(LangMan.LS(LSID.LSID_Links) + ":"); 2550 2551 int num = linkList.Count; 2552 for (int i = 0; i < num; i++) { 2553 GDMRecord rec = linkList.GetObject(i) as GDMRecord; 2554 summary.Add(" " + HyperLink(rec.XRef, linkList[i], 0)); 2555 } 2556 } 2557 2558 RecListNotesRefresh(baseContext, locRec, summary); 2559 RecListMediaRefresh(baseContext, locRec, summary); 2560 } 2561 } finally { 2562 if (linkList != null) linkList.Dispose(); 2563 summary.EndUpdate(); 2564 } 2565 } catch (Exception ex) { 2566 Logger.WriteError("GKUtils.ShowLocationInfo()", ex); 2567 } 2568 } 2569 GetRecordContent(IBaseContext baseContext, GDMRecord record, StringList ctx)2570 public static void GetRecordContent(IBaseContext baseContext, GDMRecord record, StringList ctx) 2571 { 2572 if (record != null && ctx != null) { 2573 try { 2574 switch (record.RecordType) { 2575 case GDMRecordType.rtIndividual: 2576 GKUtils.ShowPersonInfo(baseContext, record as GDMIndividualRecord, ctx); 2577 break; 2578 2579 case GDMRecordType.rtFamily: 2580 GKUtils.ShowFamilyInfo(baseContext, record as GDMFamilyRecord, ctx); 2581 break; 2582 2583 case GDMRecordType.rtNote: 2584 GKUtils.ShowNoteInfo(baseContext, record as GDMNoteRecord, ctx); 2585 break; 2586 2587 case GDMRecordType.rtMultimedia: 2588 GKUtils.ShowMultimediaInfo(baseContext, record as GDMMultimediaRecord, ctx); 2589 break; 2590 2591 case GDMRecordType.rtSource: 2592 GKUtils.ShowSourceInfo(baseContext, record as GDMSourceRecord, ctx); 2593 break; 2594 2595 case GDMRecordType.rtRepository: 2596 GKUtils.ShowRepositoryInfo(baseContext, record as GDMRepositoryRecord, ctx); 2597 break; 2598 2599 case GDMRecordType.rtGroup: 2600 GKUtils.ShowGroupInfo(baseContext, record as GDMGroupRecord, ctx); 2601 break; 2602 2603 case GDMRecordType.rtResearch: 2604 GKUtils.ShowResearchInfo(baseContext, record as GDMResearchRecord, ctx); 2605 break; 2606 2607 case GDMRecordType.rtTask: 2608 GKUtils.ShowTaskInfo(baseContext, record as GDMTaskRecord, ctx); 2609 break; 2610 2611 case GDMRecordType.rtCommunication: 2612 GKUtils.ShowCommunicationInfo(baseContext, record as GDMCommunicationRecord, ctx); 2613 break; 2614 2615 case GDMRecordType.rtLocation: 2616 GKUtils.ShowLocationInfo(baseContext, record as GDMLocationRecord, ctx); 2617 break; 2618 } 2619 } catch (Exception ex) { 2620 Logger.WriteError("GKUtils.GetRecordContext()", ex); 2621 } 2622 } 2623 } 2624 2625 #endregion 2626 2627 #region Multimedia support (static) 2628 GetStoreFolder(MultimediaKind mmKind)2629 public static string GetStoreFolder(MultimediaKind mmKind) 2630 { 2631 string result = ""; 2632 switch (mmKind) 2633 { 2634 case MultimediaKind.mkNone: 2635 result = "unknown"; 2636 break; 2637 2638 case MultimediaKind.mkImage: 2639 result = "images"; 2640 break; 2641 2642 case MultimediaKind.mkAudio: 2643 result = "audio"; 2644 break; 2645 2646 case MultimediaKind.mkText: 2647 result = "texts"; 2648 break; 2649 2650 case MultimediaKind.mkVideo: 2651 result = "video"; 2652 break; 2653 } 2654 return result + Path.DirectorySeparatorChar; 2655 } 2656 GetMultimediaKind(GDMMultimediaFormat format)2657 public static MultimediaKind GetMultimediaKind(GDMMultimediaFormat format) 2658 { 2659 switch (format) 2660 { 2661 case GDMMultimediaFormat.mfNone: 2662 return MultimediaKind.mkNone; 2663 2664 case GDMMultimediaFormat.mfBMP: 2665 case GDMMultimediaFormat.mfGIF: 2666 case GDMMultimediaFormat.mfJPG: 2667 case GDMMultimediaFormat.mfPCX: // .net isn't supports 2668 case GDMMultimediaFormat.mfTIF: 2669 case GDMMultimediaFormat.mfTGA: // .net isn't supports 2670 case GDMMultimediaFormat.mfPNG: 2671 case GDMMultimediaFormat.mfRAW: // .net isn't supports 2672 case GDMMultimediaFormat.mfPSD: // .net isn't supports 2673 return MultimediaKind.mkImage; 2674 2675 case GDMMultimediaFormat.mfTXT: 2676 case GDMMultimediaFormat.mfRTF: 2677 case GDMMultimediaFormat.mfHTM: 2678 case GDMMultimediaFormat.mfPDF: 2679 return MultimediaKind.mkText; 2680 2681 case GDMMultimediaFormat.mfWAV: 2682 case GDMMultimediaFormat.mfMP3: 2683 case GDMMultimediaFormat.mfWMA: 2684 case GDMMultimediaFormat.mfMKA: 2685 return MultimediaKind.mkAudio; 2686 2687 case GDMMultimediaFormat.mfAVI: 2688 case GDMMultimediaFormat.mfMPG: 2689 case GDMMultimediaFormat.mfMP4: 2690 case GDMMultimediaFormat.mfOGV: 2691 case GDMMultimediaFormat.mfWMV: 2692 case GDMMultimediaFormat.mfMKV: 2693 case GDMMultimediaFormat.mfMOV: 2694 return MultimediaKind.mkVideo; 2695 2696 case GDMMultimediaFormat.mfOLE: 2697 case GDMMultimediaFormat.mfUnknown: 2698 default: 2699 return MultimediaKind.mkNone; 2700 } 2701 } 2702 GetStoreTypeEx(GDMFileReference fileReference)2703 public static MediaStoreType GetStoreTypeEx(GDMFileReference fileReference) 2704 { 2705 if (fileReference == null) 2706 throw new ArgumentNullException("fileReference"); 2707 2708 string fileRef = fileReference.StringValue; 2709 MediaStoreType result = MediaStoreType.mstReference; 2710 2711 for (int i = 1; i <= 4; i++) { 2712 if (fileRef.StartsWith(GKData.GKStoreTypes[i].Sign, StringComparison.Ordinal)) { 2713 result = (MediaStoreType)i; 2714 break; 2715 } 2716 } 2717 2718 return result; 2719 } 2720 GetStoreType(GDMFileReference fileReference)2721 public static MediaStore GetStoreType(GDMFileReference fileReference) 2722 { 2723 if (fileReference == null) 2724 throw new ArgumentNullException("fileReference"); 2725 2726 string fileName = fileReference.StringValue; 2727 MediaStoreType storeType = GetStoreTypeEx(fileReference); 2728 2729 if (storeType != MediaStoreType.mstReference && storeType != MediaStoreType.mstURL) { 2730 fileName = fileName.Remove(0, 4); 2731 } 2732 2733 return new MediaStore(storeType, fileName); 2734 } 2735 UseEmbeddedViewer(GDMMultimediaFormat format)2736 public static bool UseEmbeddedViewer(GDMMultimediaFormat format) 2737 { 2738 MultimediaKind mmKind = GKUtils.GetMultimediaKind(format); 2739 2740 switch (mmKind) { 2741 case MultimediaKind.mkImage: 2742 return !(format == GDMMultimediaFormat.mfPCX || format == GDMMultimediaFormat.mfTGA || 2743 format == GDMMultimediaFormat.mfRAW || format == GDMMultimediaFormat.mfPSD); 2744 2745 case MultimediaKind.mkVideo: 2746 case MultimediaKind.mkAudio: 2747 return GlobalOptions.Instance.EmbeddedMediaPlayer; 2748 2749 case MultimediaKind.mkText: 2750 return (format == GDMMultimediaFormat.mfTXT || format == GDMMultimediaFormat.mfRTF || 2751 format == GDMMultimediaFormat.mfHTM); 2752 2753 case MultimediaKind.mkNone: 2754 default: 2755 return false; 2756 } 2757 } 2758 InitSecurityProtocol()2759 public static void InitSecurityProtocol() 2760 { 2761 // Mono v4.6 doesn't contain SecurityProtocolType.Tls11 2762 #if NET35 || NET40 || MONO 2763 const int Tls11 = 768; 2764 const int Tls12 = 3072; 2765 #endif 2766 2767 try { 2768 #if NET35 || NET40 || MONO 2769 ServicePointManager.SecurityProtocol = 2770 (SecurityProtocolType)(ServicePointManager.SecurityProtocol | 2771 SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | 2772 (SecurityProtocolType)Tls11 | (SecurityProtocolType)Tls12); 2773 #else 2774 ServicePointManager.SecurityProtocol = 2775 (SecurityProtocolType)(ServicePointManager.SecurityProtocol | 2776 SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | 2777 SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12); 2778 #endif 2779 } catch (Exception ex) { 2780 // crash on WinXP, TLS 1.2 not supported 2781 Logger.WriteError("GKUtils.InitSecurityProtocol()", ex); 2782 } 2783 } 2784 GetWebStream(string uri)2785 public static Stream GetWebStream(string uri) 2786 { 2787 InitSecurityProtocol(); 2788 2789 using (var webClient = new WebClient()) { 2790 byte[] dataBytes = webClient.DownloadData(uri); 2791 var ms = new MemoryStream(); 2792 ms.Write(dataBytes, 0, dataBytes.Length); 2793 return ms; 2794 } 2795 } 2796 2797 #endregion 2798 2799 #region Archives support (static) 2800 GetContainerName(string fileName, bool arc)2801 public static string GetContainerName(string fileName, bool arc) 2802 { 2803 string result = Path.GetFileNameWithoutExtension(fileName); 2804 if (arc) { 2805 result += ".zip"; 2806 } else { 2807 result += Path.DirectorySeparatorChar; 2808 } 2809 return result; 2810 } 2811 FileCanBeArchived(string fileName)2812 public static bool FileCanBeArchived(string fileName) 2813 { 2814 GDMMultimediaFormat fileFmt = GDMFileReference.RecognizeFormat(fileName); 2815 2816 FileInfo info = new FileInfo(fileName); 2817 double fileSize = (((double)info.Length / 1024) / 1024); // mb 2818 2819 MultimediaKind mKind = GetMultimediaKind(fileFmt); 2820 return ((mKind == MultimediaKind.mkImage || mKind == MultimediaKind.mkText) && fileSize <= 10); 2821 } 2822 2823 #endregion 2824 2825 #region Names processing 2826 GetFamilyString(GDMTree tree, GDMFamilyRecord family)2827 public static string GetFamilyString(GDMTree tree, GDMFamilyRecord family) 2828 { 2829 if (family == null) 2830 throw new ArgumentNullException("family"); 2831 2832 return GetFamilyString(tree, family, LangMan.LS(LSID.LSID_UnkMale), LangMan.LS(LSID.LSID_UnkFemale)); 2833 } 2834 GetFamilyString(GDMTree tree, GDMFamilyRecord family, string unkHusband, string unkWife)2835 public static string GetFamilyString(GDMTree tree, GDMFamilyRecord family, string unkHusband, string unkWife) 2836 { 2837 if (tree == null) 2838 throw new ArgumentNullException("tree"); 2839 2840 if (family == null) 2841 throw new ArgumentNullException("family"); 2842 2843 string result = ""; 2844 2845 GDMIndividualRecord spouse = tree.GetPtrValue(family.Husband); 2846 if (spouse == null) { 2847 if (unkHusband == null) unkHusband = "?"; 2848 result += unkHusband; 2849 } else { 2850 result += GetNameString(spouse, true, false); 2851 } 2852 2853 result += " - "; 2854 2855 spouse = tree.GetPtrValue(family.Wife); 2856 if (spouse == null) { 2857 if (unkWife == null) unkWife = "?"; 2858 result += unkWife; 2859 } else { 2860 result += GetNameString(spouse, true, false); 2861 } 2862 2863 return result; 2864 } 2865 GetNickString(GDMIndividualRecord iRec)2866 public static string GetNickString(GDMIndividualRecord iRec) 2867 { 2868 if (iRec == null) 2869 throw new ArgumentNullException("iRec"); 2870 2871 string result = (iRec.PersonalNames.Count > 0) ? iRec.PersonalNames[0].Pieces.Nickname : string.Empty; 2872 return result; 2873 } 2874 2875 // TODO: what if you want to display only a surname that is missing? GetFmtSurname(GDMSex iSex, GDMPersonalName personalName, string defSurname)2876 public static string GetFmtSurname(GDMSex iSex, GDMPersonalName personalName, string defSurname) 2877 { 2878 if (personalName == null) 2879 throw new ArgumentNullException("personalName"); 2880 2881 string result; 2882 2883 WomanSurnameFormat wsFmt = GlobalOptions.Instance.WomanSurnameFormat; 2884 if (iSex == GDMSex.svFemale && wsFmt != WomanSurnameFormat.wsfNotExtend) { 2885 string marriedSurname = personalName.Pieces.MarriedName; 2886 switch (wsFmt) { 2887 case WomanSurnameFormat.wsfMaiden_Married: 2888 result = defSurname; 2889 if (marriedSurname.Length > 0) { 2890 if (result.Length > 0) result += " "; 2891 result += "(" + marriedSurname + ")"; 2892 } 2893 break; 2894 2895 case WomanSurnameFormat.wsfMarried_Maiden: 2896 result = marriedSurname; 2897 if (defSurname.Length > 0) { 2898 if (result.Length > 0) result += " "; 2899 result += "(" + defSurname + ")"; 2900 } 2901 break; 2902 2903 case WomanSurnameFormat.wsfMaiden: 2904 result = defSurname; // by default GEDCOMPersonalName.Surname is maiden surname 2905 break; 2906 2907 case WomanSurnameFormat.wsfMarried: 2908 result = marriedSurname; 2909 break; 2910 2911 default: 2912 result = defSurname; 2913 break; 2914 } 2915 } else { 2916 result = defSurname; 2917 } 2918 2919 return result; 2920 } 2921 GetNameString(GDMIndividualRecord iRec, GDMPersonalName np, bool firstSurname, bool includePieces)2922 public static string GetNameString(GDMIndividualRecord iRec, GDMPersonalName np, bool firstSurname, bool includePieces) 2923 { 2924 if (iRec == null) 2925 throw new ArgumentNullException("iRec"); 2926 2927 if (np == null) 2928 throw new ArgumentNullException("np"); 2929 2930 string result; 2931 2932 string firstPart = np.FirstPart; 2933 string surname = np.Surname; 2934 2935 surname = GetFmtSurname(iRec.Sex, np, surname); 2936 2937 if (firstSurname) { 2938 result = surname + " " + firstPart; 2939 } else { 2940 result = firstPart + " " + surname; 2941 } 2942 2943 if (includePieces) { 2944 string nick = np.Pieces.Nickname; 2945 if (!string.IsNullOrEmpty(nick)) result = result + " [" + nick + "]"; 2946 } 2947 2948 return result.Trim(); 2949 } 2950 GetNameString(GDMIndividualRecord iRec, bool firstSurname, bool includePieces)2951 public static string GetNameString(GDMIndividualRecord iRec, bool firstSurname, bool includePieces) 2952 { 2953 if (iRec == null) 2954 throw new ArgumentNullException("iRec"); 2955 2956 string result; 2957 if (iRec.PersonalNames.Count > 0) { 2958 GDMPersonalName np = iRec.PersonalNames[0]; 2959 result = GetNameString(iRec, np, firstSurname, includePieces); 2960 } else { 2961 result = ""; 2962 } 2963 return result; 2964 } 2965 SetMarriedSurname(GDMIndividualRecord iRec, string marriedSurname)2966 public static void SetMarriedSurname(GDMIndividualRecord iRec, string marriedSurname) 2967 { 2968 if (iRec == null) 2969 throw new ArgumentNullException("iRec"); 2970 2971 GDMPersonalName personalName; 2972 if (iRec.PersonalNames.Count <= 0) { 2973 personalName = iRec.AddPersonalName(new GDMPersonalName()); 2974 } else { 2975 personalName = iRec.PersonalNames[0]; 2976 } 2977 2978 personalName.Pieces.MarriedName = marriedSurname.Trim(); 2979 } 2980 SetNameParts(GDMPersonalName personalName, string surname, string name, string patronymic)2981 public static void SetNameParts(GDMPersonalName personalName, string surname, string name, string patronymic) 2982 { 2983 if (personalName == null) 2984 throw new ArgumentNullException("personalName"); 2985 2986 surname = surname.Trim(); 2987 name = name.Trim(); 2988 patronymic = patronymic.Trim(); 2989 2990 personalName.SetNameParts(name + " " + patronymic, surname, personalName.LastPart); 2991 2992 var pnPieces = personalName.Pieces; 2993 pnPieces.Surname = surname; 2994 pnPieces.Given = name; 2995 pnPieces.PatronymicName = patronymic; 2996 } 2997 GetNameParts(GDMTree tree, GDMIndividualRecord iRec, GDMPersonalName personalName, bool formatted = true)2998 public static NamePartsRet GetNameParts(GDMTree tree, GDMIndividualRecord iRec, GDMPersonalName personalName, bool formatted = true) 2999 { 3000 if (iRec == null) 3001 throw new ArgumentNullException("iRec"); 3002 3003 ICulture culture = DefineCulture(tree, personalName); 3004 3005 NamePartsRet nameParts = culture.GetNameParts(personalName); 3006 3007 if (formatted) { 3008 nameParts.Surname = GetFmtSurname(iRec.Sex, personalName, nameParts.Surname); 3009 } 3010 3011 return nameParts; 3012 } 3013 GetNameParts(GDMTree tree, GDMIndividualRecord iRec, bool formatted = true)3014 public static NamePartsRet GetNameParts(GDMTree tree, GDMIndividualRecord iRec, bool formatted = true) 3015 { 3016 if (iRec == null) 3017 throw new ArgumentNullException("iRec"); 3018 3019 if (iRec.PersonalNames.Count > 0) { 3020 return GetNameParts(tree, iRec, iRec.PersonalNames[0], formatted); 3021 } else { 3022 return new NamePartsRet(); 3023 } 3024 } 3025 DefineCulture(GDMTree tree, GDMPersonalName personalName)3026 public static ICulture DefineCulture(GDMTree tree, GDMPersonalName personalName) 3027 { 3028 // first priority - local langID from name 3029 GDMLanguageID langID = (personalName != null) ? personalName.Language : GDMLanguageID.Unknown; 3030 3031 // second priority - global langID from tree 3032 if (langID == GDMLanguageID.Unknown && tree != null) { 3033 langID = tree.Header.Language; 3034 } 3035 3036 return CulturesPool.DefineCulture(langID); 3037 } 3038 3039 #endregion 3040 } 3041 } 3042