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 #define GEDML_SUPPORT
22 #define FAMX_SUPPORT
23 
24 using System;
25 using System.Collections.Generic;
26 using System.IO;
27 using BSLib;
28 using BSLib.Design.Graphics;
29 using BSLib.Design.MVP;
30 using BSLib.Design.MVP.Controls;
31 using GDModel;
32 using GKCore.Charts;
33 using GKCore.Export;
34 using GKCore.Interfaces;
35 using GKCore.MVP.Controls;
36 using GKCore.MVP.Views;
37 using GKCore.Options;
38 using GKCore.Types;
39 
40 namespace GKCore.Controllers
41 {
42     public sealed class TabParts
43     {
44         public readonly IListViewEx ListView;
45         public readonly IHyperView Summary;
46 
TabParts(IListViewEx listView, IHyperView summary)47         public TabParts(IListViewEx listView, IHyperView summary)
48         {
49             ListView = listView;
50             Summary = summary;
51         }
52     }
53 
54     /// <summary>
55     ///
56     /// </summary>
57     public sealed class BaseWinController : Controller<IBaseWindowView>
58     {
59         private readonly List<GDMRecord> fChangedRecords;
60         private readonly IBaseContext fContext;
61         private GDMRecord fDelayedTransitionRecord;
62         private readonly NavigationStack<GDMRecord> fNavman;
63         private readonly TabParts[] fTabParts;
64 
65         public IBaseContext Context
66         {
67             get { return fContext; }
68         }
69 
70         public NavigationStack<GDMRecord> Navman
71         {
72             get { return fNavman; }
73         }
74 
75 
BaseWinController(IBaseWindowView view)76         public BaseWinController(IBaseWindowView view) : base(view)
77         {
78             fContext = new BaseContext(view);
79             fChangedRecords = new List<GDMRecord>();
80             fNavman = new NavigationStack<GDMRecord>();
81             fTabParts = new TabParts[(int)GDMRecordType.rtLast + 1];
82         }
83 
Dispose(bool disposing)84         protected override void Dispose(bool disposing)
85         {
86             if (disposing) {
87                 //fNavman.Dispose();
88                 fContext.Dispose();
89             }
90             base.Dispose(disposing);
91         }
92 
93         #region Context
94 
Clear()95         public void Clear()
96         {
97             fNavman.Clear();
98             fContext.Clear();
99         }
100 
101         // FIXME: Identify and test the need for this method
CreateNewFile()102         public void CreateNewFile()
103         {
104             Clear();
105             RefreshLists(false);
106             ClearSummaries();
107             fContext.SetFileName(LangMan.LS(LSID.LSID_Unknown));
108             fContext.Tree.Header.Language = GlobalOptions.Instance.GetCurrentItfLang();
109             fContext.Modified = false;
110         }
111 
NewFile()112         public void NewFile()
113         {
114             AppHost.Instance.CreateBase("");
115         }
116 
LoadFile(string fileName)117         public void LoadFile(string fileName)
118         {
119             Clear();
120 
121             if (fContext.FileLoad(fileName)) {
122                 fContext.Modified = false;
123                 ChangeFileName();
124                 RefreshLists(false);
125                 fView.Activate();
126             }
127         }
128 
LoadFileEx()129         public void LoadFileEx()
130         {
131             string homePath = AppHost.Instance.GetUserFilesPath("");
132 
133             string filters = LangMan.LS(LSID.LSID_GEDCOMFilter);
134 
135             #if GEDML_SUPPORT
136             filters += "|" + LangMan.LS(LSID.LSID_GedMLFilter);
137             #endif
138 
139             #if FAMX_SUPPORT
140             filters += "|" + "Family.Show files (*.familyx)|*.familyx";
141             #endif
142 
143             string fileName = AppHost.StdDialogs.GetOpenFile("", homePath, filters, 1, GKData.GEDCOM_EXT);
144             if (!string.IsNullOrEmpty(fileName)) {
145                 AppHost.Instance.LoadBase(fView, fileName);
146             }
147         }
148 
SaveFile(string fileName)149         public void SaveFile(string fileName)
150         {
151             if (fContext.FileSave(fileName)) {
152                 fContext.Modified = false;
153                 ChangeFileName();
154             }
155         }
156 
SaveFileEx(bool saveAs)157         public void SaveFileEx(bool saveAs)
158         {
159             string oldFileName = fContext.FileName;
160             bool isUnknown = fContext.IsUnknown();
161 
162             if (!isUnknown && !saveAs) {
163                 SaveFile(oldFileName);
164             } else {
165                 string homePath = AppHost.Instance.GetUserFilesPath(Path.GetDirectoryName(oldFileName));
166                 string newFileName = AppHost.StdDialogs.GetSaveFile("", homePath, LangMan.LS(LSID.LSID_GEDCOMFilter), 1, GKData.GEDCOM_EXT, oldFileName, false);
167                 if (!string.IsNullOrEmpty(newFileName)) {
168                     SaveFile(newFileName);
169                     if (!isUnknown && !string.Equals(oldFileName, newFileName)) {
170                         AppHost.Instance.BaseRenamed(fView, oldFileName, newFileName);
171                     }
172                 }
173             }
174         }
175 
CheckAutosave()176         public void CheckAutosave()
177         {
178             // file is modified, isn't updated now, and isn't now created (exists)
179             if (fContext.Modified && !fContext.IsUpdated() && !fContext.IsUnknown()) {
180                 // TODO: if file is new and not exists - don't save it, but hint to user
181                 SaveFile(fContext.FileName);
182             }
183         }
184 
ApplyFilter(GDMRecordType recType = GDMRecordType.rtNone)185         public void ApplyFilter(GDMRecordType recType = GDMRecordType.rtNone)
186         {
187             if (fContext.Tree.RecordsCount > 0) {
188                 if (recType == GDMRecordType.rtNone) {
189                     RefreshLists(false);
190                 } else {
191                     RefreshRecordsView(recType);
192                 }
193             }
194         }
195 
SetExternalFilter(ExternalFilterHandler filterHandler, GDMRecordType recType = GDMRecordType.rtNone)196         public void SetExternalFilter(ExternalFilterHandler filterHandler,
197                                       GDMRecordType recType = GDMRecordType.rtNone)
198         {
199             for (var rt = GDMRecordType.rtIndividual; rt <= GDMRecordType.rtLocation; rt++) {
200                 if (recType != GDMRecordType.rtNone && recType != rt) continue;
201 
202                 IListViewEx listview = fTabParts[(int)rt].ListView;
203                 if (listview != null) {
204                     listview.ListMan.ExternalFilter = filterHandler;
205                 }
206             }
207         }
208 
NotifyRecord(GDMRecord record, RecordAction action)209         public void NotifyRecord(GDMRecord record, RecordAction action)
210         {
211             if (record == null) return;
212 
213             DateTime dtNow = DateTime.Now;
214 
215             switch (action) {
216                 case RecordAction.raAdd:
217                 case RecordAction.raEdit:
218                     record.ChangeDate.ChangeDateTime = dtNow;
219                     CheckChangedRecord(record, true);
220                     break;
221 
222                 case RecordAction.raDelete:
223                     {
224                         CheckChangedRecord(record, false);
225 
226                         IListViewEx rView = GetRecordsViewByType(record.RecordType);
227                         if (rView != null) {
228                             rView.DeleteRecord(record);
229 
230                             IHyperView hView = GetHyperViewByType(record.RecordType);
231                             if ((hView != null) && (rView.ListMan.FilteredCount == 0)) {
232                                 hView.Lines.Clear();
233                             }
234                         }
235                     }
236                     break;
237 
238                 case RecordAction.raJump:
239                     break;
240 
241                 case RecordAction.raMoveUp:
242                 case RecordAction.raMoveDown:
243                     break;
244             }
245 
246             if (action != RecordAction.raJump) {
247                 fContext.Tree.Header.TransmissionDateTime = dtNow;
248                 fContext.Modified = true;
249 
250                 AppHost.Instance.NotifyRecord(fView, record, action);
251             }
252         }
253 
DuplicateRecord()254         public void DuplicateRecord()
255         {
256             GDMRecord original = GetSelectedRecordEx();
257             if (original == null || original.RecordType != GDMRecordType.rtIndividual) return;
258 
259             AppHost.StdDialogs.ShowWarning(LangMan.LS(LSID.LSID_DuplicateWarning));
260 
261             GDMIndividualRecord target;
262             try {
263                 fContext.BeginUpdate();
264 
265                 target = fContext.Tree.CreateIndividual();
266                 target.Assign(original);
267 
268                 NotifyRecord(target, RecordAction.raAdd);
269             } finally {
270                 fContext.EndUpdate();
271             }
272 
273             RefreshLists(false);
274             fView.SelectRecordByXRef(target.XRef);
275         }
276 
AddRecord()277         public void AddRecord()
278         {
279             GDMRecordType rt = GetSelectedRecordType();
280 
281             GDMRecord record = BaseController.AddRecord(fView, rt, null);
282             if (record != null) {
283                 RefreshLists(false);
284             }
285 
286             UpdateChangedRecords(record);
287         }
288 
EditRecord()289         public void EditRecord()
290         {
291             GDMRecord record = GetSelectedRecordEx();
292             if (record != null && BaseController.EditRecord(fView, record)) {
293                 RefreshLists(false);
294             }
295 
296             UpdateChangedRecords(record);
297         }
298 
DeleteRecord()299         public void DeleteRecord()
300         {
301             GDMRecord record = GetSelectedRecordEx();
302             if (record != null && BaseController.DeleteRecord(fView, record, true)) {
303                 RefreshLists(false);
304             }
305         }
306 
ShowRecordInfo(GDMRecord record)307         public void ShowRecordInfo(GDMRecord record)
308         {
309             if (record == null) return;
310 
311             try {
312                 IHyperView hyperView = GetHyperViewByType(record.RecordType);
313                 if (hyperView != null) {
314                     GKUtils.GetRecordContent(fContext, record, hyperView.Lines);
315                 }
316             } catch (Exception ex) {
317                 Logger.WriteError("BaseWinSDI.ShowRecordInfo()", ex);
318             }
319         }
320 
ChangeListItem(IListViewEx sender)321         public void ChangeListItem(IListViewEx sender)
322         {
323             GDMRecord rec = sender.GetSelectedData() as GDMRecord;
324             if (rec != null) {
325                 NavAdd(rec);
326             }
327             ShowRecordInfo(rec);
328         }
329 
SelectSummaryLink(string linkName)330         public void SelectSummaryLink(string linkName)
331         {
332             if (linkName.StartsWith("http")) {
333                 GKUtils.LoadExtFile(linkName);
334                 return;
335             }
336 
337             if (linkName.StartsWith("view_")) {
338                 string xref = linkName.Remove(0, 5);
339                 var mmRec = fContext.Tree.FindXRef<GDMMultimediaRecord>(xref);
340                 if (mmRec != null) {
341                     fView.ShowMedia(mmRec, false);
342                 }
343             } else {
344                 SelectRecordByXRef(linkName);
345             }
346         }
347 
SelectByRec(GDMRecord record)348         public void SelectByRec(GDMRecord record)
349         {
350             if (record == null)
351                 throw new ArgumentNullException("record");
352 
353             fView.Activate();
354             SelectRecordByXRef(record.XRef);
355         }
356 
SelectRecordByXRef(string xref, bool delayedTransition = false)357         public void SelectRecordByXRef(string xref, bool delayedTransition = false)
358         {
359             GDMRecord record = fContext.Tree.XRefIndex_Find(xref);
360 
361             if (delayedTransition) {
362                 fDelayedTransitionRecord = record;
363                 return;
364             }
365 
366             if (fDelayedTransitionRecord != null) {
367                 record = fDelayedTransitionRecord;
368                 fDelayedTransitionRecord = null;
369             }
370 
371             IListViewEx rView = (record == null) ? null : GetRecordsViewByType(record.RecordType);
372             if (rView != null) {
373                 fView.ShowRecordsTab(record.RecordType);
374                 rView.Activate();
375                 rView.SelectItem(record);
376             }
377         }
378 
GetRecordContent(GDMRecord record)379         public StringList GetRecordContent(GDMRecord record)
380         {
381             StringList ctx = new StringList();
382             GKUtils.GetRecordContent(fContext, record, ctx);
383             return ctx;
384         }
385 
RecordIsFiltered(GDMRecord record)386         public bool RecordIsFiltered(GDMRecord record)
387         {
388             bool result = false;
389             if (record != null) {
390                 IListViewEx rView = GetRecordsViewByType(record.RecordType);
391                 result = (rView != null && rView.ListMan.IndexOfRecord(record) >= 0);
392             }
393             return result;
394         }
395 
Undo()396         public void Undo()
397         {
398             fContext.DoUndo();
399         }
400 
Redo()401         public void Redo()
402         {
403             fContext.DoRedo();
404         }
405 
406         #endregion
407 
408         #region UI
409 
SetTabPart(GDMRecordType recType, IListViewEx listView, IHyperView summary)410         public void SetTabPart(GDMRecordType recType, IListViewEx listView, IHyperView summary)
411         {
412             fTabParts[(int)recType] = new TabParts(listView, summary);
413         }
414 
GetSelectedRecordType()415         public GDMRecordType GetSelectedRecordType()
416         {
417             return (GDMRecordType)(fView.RecordTabs.SelectedIndex + 1);
418         }
419 
GetRecordsViewByType(GDMRecordType recType)420         public IListViewEx GetRecordsViewByType(GDMRecordType recType)
421         {
422             int rt = (int)recType;
423             TabParts tabPart = (rt < 0 || rt >= fTabParts.Length) ? null : fTabParts[rt];
424             return (tabPart == null) ? null : tabPart.ListView;
425         }
426 
427         /// <summary>
428         /// Gets a hyper-view control for the specified record type.
429         /// </summary>
430         /// <param name="recType">Record type for which a hyper view control is
431         /// required.</param>
432         /// <returns>Hyper view control.</returns>
GetHyperViewByType(GDMRecordType recType)433         public IHyperView GetHyperViewByType(GDMRecordType recType)
434         {
435             IHyperView view = fTabParts[(int)recType].Summary;
436             return view;
437         }
438 
GetRecordsListManByType(GDMRecordType recType)439         public IListManager GetRecordsListManByType(GDMRecordType recType)
440         {
441             IListViewEx rView = GetRecordsViewByType(recType);
442             return (rView == null) ? null : rView.ListMan;
443         }
444 
GetSelectedRecordEx()445         public GDMRecord GetSelectedRecordEx()
446         {
447             GDMRecordType recType = GetSelectedRecordType();
448             IListViewEx rView = GetRecordsViewByType(recType);
449             return (rView == null) ? null : (rView.GetSelectedData() as GDMRecord);
450         }
451 
GetSelectedPerson()452         public GDMIndividualRecord GetSelectedPerson()
453         {
454             return GetSelectedRecordEx() as GDMIndividualRecord;
455         }
456 
ClearSummaries()457         public void ClearSummaries()
458         {
459             for (var rt = GDMRecordType.rtIndividual; rt <= GDMRecordType.rtLocation; rt++) {
460                 IHyperView summary = fTabParts[(int)rt].Summary;
461                 if (summary != null) {
462                     summary.Lines.Clear();
463                 }
464             }
465         }
466 
RefreshLists(bool columnsChanged)467         public void RefreshLists(bool columnsChanged)
468         {
469             for (var rt = GDMRecordType.rtIndividual; rt <= GDMRecordType.rtLocation; rt++) {
470                 IListViewEx listview = fTabParts[(int)rt].ListView;
471                 if (listview != null) {
472                     listview.UpdateContents(columnsChanged);
473                 }
474             }
475 
476             AppHost.Instance.UpdateControls(false);
477         }
478 
GetContentList(GDMRecordType recType)479         public List<GDMRecord> GetContentList(GDMRecordType recType)
480         {
481             IListViewEx rView = GetRecordsViewByType(recType);
482             return (rView == null) ? null : rView.ListMan.GetRecordsList();
483         }
484 
RestoreListsSettings()485         public void RestoreListsSettings()
486         {
487             var globOptions = GlobalOptions.Instance;
488             for (var rt = GDMRecordType.rtIndividual; rt <= GDMRecordType.rtLocation; rt++) {
489                 IListViewEx rView = fTabParts[(int)rt].ListView;
490                 if (rView != null) {
491                     rView.SetSortColumn(globOptions.ListOptions[rt].SortColumn, false);
492                     if (rt == GDMRecordType.rtIndividual) {
493                         globOptions.IndividualListColumns.CopyTo(rView.ListMan.ListColumns);
494                     }
495                 }
496             }
497         }
498 
SaveListsSettings()499         public void SaveListsSettings()
500         {
501             var globOptions = GlobalOptions.Instance;
502             for (var rt = GDMRecordType.rtIndividual; rt <= GDMRecordType.rtLocation; rt++) {
503                 IListViewEx rView = fTabParts[(int)rt].ListView;
504                 if (rView != null) {
505                     globOptions.ListOptions[rt].SortColumn = rView.SortColumn;
506                     if (rt == GDMRecordType.rtIndividual) {
507                         rView.ListMan.ListColumns.CopyTo(globOptions.IndividualListColumns);
508                     }
509                 }
510             }
511         }
512 
RefreshRecordsView(GDMRecordType recType)513         public void RefreshRecordsView(GDMRecordType recType)
514         {
515             IListViewEx rView = GetRecordsViewByType(recType);
516             if (rView != null) {
517                 rView.UpdateContents();
518 
519                 AppHost.Instance.UpdateControls(false);
520             }
521         }
522 
UpdateChangedRecords(GDMRecord select = null)523         public void UpdateChangedRecords(GDMRecord select = null)
524         {
525             for (int i = fChangedRecords.Count - 1; i >= 0; i--) {
526                 var record = fChangedRecords[i];
527 
528                 RefreshRecordsView(record.RecordType);
529             }
530 
531             if (select != null) {
532                 fView.SelectRecordByXRef(select.XRef);
533             }
534         }
535 
CheckChangedRecord(GDMRecord record, bool active)536         public void CheckChangedRecord(GDMRecord record, bool active)
537         {
538             int idx = fChangedRecords.IndexOf(record);
539             if (active) {
540                 if (idx < 0) {
541                     fChangedRecords.Add(record);
542                 }
543             } else {
544                 if (idx >= 0) {
545                     fChangedRecords.RemoveAt(idx);
546                 }
547             }
548         }
549 
UpdateSettings()550         public void UpdateSettings()
551         {
552             RestoreListsSettings();
553             RefreshLists(true);
554         }
555 
NavAdd(GDMRecord aRec)556         public void NavAdd(GDMRecord aRec)
557         {
558             if (aRec == null) return;
559 
560             fNavman.Current = aRec;
561             AppHost.Instance.UpdateControls(false);
562         }
563 
NavNext()564         public void NavNext()
565         {
566             GDMRecord rec = fNavman.Next();
567             if (rec != null) {
568                 fView.SelectRecordByXRef(rec.XRef);
569                 AppHost.Instance.UpdateControls(false);
570             }
571         }
572 
NavPrev()573         public void NavPrev()
574         {
575             GDMRecord rec = fNavman.Back();
576             if (rec != null) {
577                 fView.SelectRecordByXRef(rec.XRef);
578                 AppHost.Instance.UpdateControls(false);
579             }
580         }
581 
NavCanBackward()582         public bool NavCanBackward()
583         {
584             return fNavman.CanBackward();
585         }
586 
NavCanForward()587         public bool NavCanForward()
588         {
589             return fNavman.CanForward();
590         }
591 
SetMainTitle()592         public void SetMainTitle()
593         {
594             string caption = Path.GetFileName(fContext.FileName);
595             if (fContext.Modified) {
596                 caption = @"* " + caption;
597             }
598             fView.Title = caption;
599         }
600 
ChangeFileName()601         public void ChangeFileName()
602         {
603             SetMainTitle();
604             GlobalOptions.Instance.LastDir = Path.GetDirectoryName(fContext.FileName);
605             AppHost.Instance.AddMRU(fContext.FileName);
606         }
607 
FindAll(string searchPattern)608         public IList<ISearchResult> FindAll(string searchPattern)
609         {
610             GDMRecordType rt = GetSelectedRecordType();
611             IListManager listMan = GetRecordsListManByType(rt);
612             IList<ISearchResult> result = (listMan == null) ? new List<ISearchResult>() : listMan.FindAll(searchPattern);
613             return result;
614         }
615 
SetFilter()616         public void SetFilter()
617         {
618             if (!fView.AllowFilter()) return;
619 
620             GDMRecordType rt = GetSelectedRecordType();
621             IListManager listMan = GetRecordsListManByType(rt);
622             if (listMan == null) return;
623 
624             switch (rt) {
625                 case GDMRecordType.rtIndividual:
626                     ShowPersonsFilter(rt, listMan);
627                     break;
628 
629                 case GDMRecordType.rtFamily:
630                 case GDMRecordType.rtNote:
631                 case GDMRecordType.rtMultimedia:
632                 case GDMRecordType.rtSource:
633                 case GDMRecordType.rtRepository:
634                 case GDMRecordType.rtGroup:
635                 case GDMRecordType.rtResearch:
636                 case GDMRecordType.rtTask:
637                 case GDMRecordType.rtCommunication:
638                 case GDMRecordType.rtLocation:
639                     ShowCommonFilter(rt, listMan);
640                     break;
641             }
642         }
643 
GetShieldImage()644         public IImage GetShieldImage()
645         {
646             IImage img = null;
647             var gfxProvider = AppHost.GfxProvider;
648             switch (fContext.ShieldState) {
649                 case ShieldState.None:
650                     img = gfxProvider.LoadResourceImage("rg_shield_none.gif", true);
651                     break;
652                 case ShieldState.Middle:
653                     img = gfxProvider.LoadResourceImage("rg_shield_mid.gif", true);
654                     break;
655                 case ShieldState.Maximum:
656                     img = gfxProvider.LoadResourceImage("rg_shield_max.gif", true);
657                     break;
658             }
659             return img;
660         }
661 
662         #endregion
663 
UpdateView()664         public override void UpdateView()
665         {
666         }
667 
668         #region Dialogs
669 
ShowCommonFilter(GDMRecordType rt, IListManager listMan)670         private void ShowCommonFilter(GDMRecordType rt, IListManager listMan)
671         {
672             using (var dlg = AppHost.Container.Resolve<ICommonFilterDlg>(fView, listMan)) {
673                 if (AppHost.Instance.ShowModalX(dlg, false)) {
674                     ApplyFilter(rt);
675                 }
676             }
677         }
678 
ShowPersonsFilter(GDMRecordType rt, IListManager listMan)679         private void ShowPersonsFilter(GDMRecordType rt, IListManager listMan)
680         {
681             using (var dlg = AppHost.Container.Resolve<IPersonsFilterDlg>(fView, listMan)) {
682                 if (AppHost.Instance.ShowModalX(dlg, false)) {
683                     ApplyFilter(rt);
684                 }
685             }
686         }
687 
ExportToFamilyBook()688         public void ExportToFamilyBook()
689         {
690             //#if MONO
691             //AppHost.StdDialogs.ShowWarning(@"This function is not supported in Linux");
692             //#else
693             //#endif
694 
695             using (FamilyBookExporter fb = new FamilyBookExporter(fView)) {
696                 fb.Generate(true);
697             }
698         }
699 
ExportToTreesAlbum()700         public void ExportToTreesAlbum()
701         {
702             //#if MONO
703             //AppHost.StdDialogs.ShowWarning(@"This function is not supported in Linux");
704             //#else
705             //#endif
706 
707             AppHost.StdDialogs.ShowWarning(@"This function is experimental and not completed. Only for PDF!");
708 
709             using (TreesAlbumExporter ta = new TreesAlbumExporter(fView)) {
710                 ta.Generate(true);
711             }
712         }
713 
ExportToExcelFile()714         public void ExportToExcelFile()
715         {
716             using (ExcelExporter exExp = new ExcelExporter(fView)) {
717                 exExp.Options = AppHost.Options;
718                 exExp.Generate(true);
719             }
720         }
721 
ShowFileProperties()722         public void ShowFileProperties()
723         {
724             try {
725                 fContext.BeginUpdate();
726 
727                 using (var dlg = AppHost.ResolveDialog<IFilePropertiesDlg>(fView)) {
728                     AppHost.Instance.ShowModalX(dlg, false);
729                 }
730             } finally {
731                 fContext.EndUpdate();
732             }
733         }
734 
ShowScripts()735         public void ShowScripts()
736         {
737             try {
738                 fContext.BeginUpdate();
739 
740                 using (var dlg = AppHost.Container.Resolve<IScriptEditWin>(fView)) {
741                     AppHost.Instance.ShowModalX(dlg, false);
742                 }
743             } finally {
744                 fContext.EndUpdate();
745             }
746         }
747 
ShowTreeSplit()748         public void ShowTreeSplit()
749         {
750             try {
751                 fContext.BeginUpdate();
752                 using (var dlg = AppHost.Container.Resolve<ITreeSplitDlg>(fView)) {
753                     AppHost.Instance.ShowModalX(dlg, false);
754                 }
755             } finally {
756                 fContext.EndUpdate();
757             }
758         }
759 
ShowTreeMerge()760         public void ShowTreeMerge()
761         {
762             try {
763                 fContext.BeginUpdate();
764                 using (var dlg = AppHost.Container.Resolve<ITreeMergeDlg>(fView)) {
765                     AppHost.Instance.ShowModalX(dlg, false);
766                 }
767             } finally {
768                 fContext.EndUpdate();
769             }
770         }
771 
ShowTreeCompare()772         public void ShowTreeCompare()
773         {
774             try {
775                 fContext.BeginUpdate();
776                 using (var dlg = AppHost.Container.Resolve<ITreeCompareDlg>(fView)) {
777                     AppHost.Instance.ShowModalX(dlg, false);
778                 }
779             } finally {
780                 fContext.EndUpdate();
781             }
782         }
783 
ShowTreeCheck()784         public void ShowTreeCheck()
785         {
786             try {
787                 fContext.BeginUpdate();
788                 using (var dlg = AppHost.Container.Resolve<ITreeCheckDlg>(fView)) {
789                     AppHost.Instance.ShowModalX(dlg, false);
790                 }
791             } finally {
792                 fContext.EndUpdate();
793             }
794         }
795 
ShowRecMerge(GDMRecord rec1, GDMRecord rec2)796         public void ShowRecMerge(GDMRecord rec1, GDMRecord rec2)
797         {
798             try {
799                 fContext.BeginUpdate();
800                 using (var dlg = AppHost.Container.Resolve<IRecMergeDlg>(fView)) {
801                     dlg.MergeCtl.SetRec1(rec1);
802                     dlg.MergeCtl.SetRec2(rec2);
803                     AppHost.Instance.ShowModalX(dlg, false);
804                 }
805             } finally {
806                 fContext.EndUpdate();
807             }
808         }
809 
ShowPlacesManager()810         public void ShowPlacesManager()
811         {
812             try {
813                 fContext.BeginUpdate();
814                 using (var dlg = AppHost.Container.Resolve<IPlacesManagerDlg>(fView)) {
815                     AppHost.Instance.ShowModalX(dlg, false);
816                 }
817             } finally {
818                 fContext.EndUpdate();
819             }
820         }
821 
ShowPatSearch()822         public void ShowPatSearch()
823         {
824             try {
825                 fContext.BeginUpdate();
826                 using (var dlg = AppHost.Container.Resolve<IPatriarchsSearchDlg>(fView)) {
827                     AppHost.Instance.ShowModalX(dlg, false);
828                 }
829             } finally {
830                 fContext.EndUpdate();
831             }
832         }
833 
ShowFamilyGroups()834         public void ShowFamilyGroups()
835         {
836             try {
837                 fContext.BeginUpdate();
838                 using (var dlg = AppHost.Container.Resolve<IFragmentSearchDlg>(fView)) {
839                     AppHost.Instance.ShowModalX(dlg, false);
840                 }
841             } finally {
842                 fContext.EndUpdate();
843             }
844         }
845 
SendMail()846         public void SendMail()
847         {
848             if (fView.CheckModified()) {
849                 string fileName = Path.GetFileName(fContext.FileName);
850                 SysUtils.SendMail("?", fileName, "?", fContext.FileName);
851             }
852         }
853 
ShowMap()854         public void ShowMap()
855         {
856             //#if MONO
857             //AppHost.StdDialogs.ShowWarning(@"This function is not supported in Linux");
858             //#else
859             var mapsWin = AppHost.Container.Resolve<IMapsViewerWin>(fView);
860             AppHost.Instance.ShowWindow(mapsWin);
861             //#endif
862         }
863 
ShowOrganizer()864         public void ShowOrganizer()
865         {
866             using (var dlg = AppHost.Container.Resolve<IOrganizerWin>(fView)) {
867                 AppHost.Instance.ShowModalX(dlg, false);
868             }
869         }
870 
ShowRelationshipCalculator()871         public void ShowRelationshipCalculator()
872         {
873             using (var dlg = AppHost.Container.Resolve<IRelationshipCalculatorDlg>(fView)) {
874                 AppHost.Instance.ShowModalX(dlg, false);
875             }
876         }
877 
ShowSlideshow()878         public void ShowSlideshow()
879         {
880             var win = AppHost.Container.Resolve<ISlideshowWin>(fView);
881             AppHost.Instance.ShowWindow(win);
882         }
883 
ShowStats()884         public void ShowStats()
885         {
886             List<GDMRecord> selectedRecords = GetContentList(GDMRecordType.rtIndividual);
887 
888             var win = AppHost.Container.Resolve<IStatisticsWin>(fView, selectedRecords);
889             AppHost.Instance.ShowWindow(win);
890         }
891 
GeneratePedigree(PedigreeExporter.PedigreeKind kind)892         public void GeneratePedigree(PedigreeExporter.PedigreeKind kind)
893         {
894             var selPerson = GetSelectedPerson();
895             if (selPerson == null) {
896                 AppHost.StdDialogs.ShowError(LangMan.LS(LSID.LSID_NotSelectedPerson));
897                 return;
898             }
899 
900             if (BaseController.DetectCycle(fContext.Tree, selPerson)) return;
901 
902             using (var p = new PedigreeExporter(fView, selPerson)) {
903                 p.Options = AppHost.Options;
904                 p.Kind = kind;
905                 p.Generate(true);
906             }
907         }
908 
ShowTreeChart(TreeChartKind chartKind)909         public void ShowTreeChart(TreeChartKind chartKind)
910         {
911             var selPerson = GetSelectedPerson();
912             if (selPerson == null) return;
913 
914             if (BaseController.DetectCycle(fContext.Tree, selPerson)) return;
915 
916             if (TreeChartModel.CheckTreeChartSize(fContext.Tree, selPerson, chartKind)) {
917                 var fmChart = AppHost.Container.Resolve<ITreeChartWin>(fView, selPerson);
918                 fmChart.GenChart(chartKind);
919                 AppHost.Instance.ShowWindow(fmChart);
920             }
921         }
922 
ShowCircleChart(CircleChartType chartKind)923         public void ShowCircleChart(CircleChartType chartKind)
924         {
925             var selPerson = GetSelectedPerson();
926             if (selPerson == null) return;
927 
928             if (BaseController.DetectCycle(fContext.Tree, selPerson)) return;
929 
930             var fmChart = AppHost.Container.Resolve<ICircleChartWin>(fView, selPerson, chartKind);
931             AppHost.Instance.ShowWindow(fmChart);
932         }
933 
SendLog()934         public void SendLog()
935         {
936             SysUtils.SendMail(GKData.APP_MAIL, "GEDKeeper: feedback", "This automatic notification of error.", AppHost.GetLogFilename());
937         }
938 
ShowLog()939         public void ShowLog()
940         {
941             GKUtils.LoadExtFile(AppHost.GetLogFilename());
942         }
943 
ShowAbout()944         public void ShowAbout()
945         {
946             using (var dlg = AppHost.Container.Resolve<IAboutDlg>()) {
947                 AppHost.Instance.ShowModalX(dlg, false);
948             }
949         }
950 
Plugin_Click(IMenuItem sender)951         private static void Plugin_Click(IMenuItem sender)
952         {
953             if (sender == null) return;
954 
955             IPlugin plugin = sender.Tag as IPlugin;
956             if (plugin == null) return;
957 
958             plugin.Execute();
959         }
960 
UpdatePluginsItems()961         public void UpdatePluginsItems()
962         {
963             try {
964                 fView.PluginsItem.ClearItems();
965                 fView.ReportsItem.ClearItems();
966 
967                 AppHost.Instance.ActiveWidgets.Clear();
968 
969                 int num = AppHost.Plugins.Count;
970                 for (int i = 0; i < num; i++) {
971                     IPlugin plugin = AppHost.Plugins[i];
972 
973                     if (plugin is IDialogReplacement || plugin.Category == PluginCategory.DialogReplacement) {
974                         continue;
975                     }
976 
977                     IMenuItem ownerItem = (plugin.Category == PluginCategory.Report) ? fView.ReportsItem : fView.PluginsItem;
978                     IMenuItem mi = ownerItem.AddItem(plugin.DisplayName, plugin, plugin.Icon, Plugin_Click);
979 
980                     var widget = plugin as IWidget;
981                     if (widget != null) {
982                         var widInfo = new WidgetInfo(widget, mi);
983                         AppHost.Instance.ActiveWidgets.Add(widInfo);
984                         widget.WidgetInit(AppHost.Instance);
985                     }
986                 }
987 
988                 fView.ReportsItem.Enabled = (fView.ReportsItem.ItemsCount > 0);
989                 fView.PluginsItem.Enabled = (fView.PluginsItem.ItemsCount > 0);
990             } catch (Exception ex) {
991                 Logger.WriteError("BaseWinController.UpdatePluginsItems()", ex);
992             }
993         }
994 
995         #endregion
996     }
997 }
998