diff --git a/Source/WPF/MyMoney/MainWindow.xaml.cs b/Source/WPF/MyMoney/MainWindow.xaml.cs
index 1a1899c3..b8d1f9e2 100644
--- a/Source/WPF/MyMoney/MainWindow.xaml.cs
+++ b/Source/WPF/MyMoney/MainWindow.xaml.cs
@@ -22,6 +22,7 @@
using Walkabout.Data;
using Walkabout.Dialogs;
using Walkabout.Help;
+using Walkabout.Interfaces.Reports;
using Walkabout.Interfaces.Views;
using Walkabout.Migrate;
using Walkabout.Ofx;
@@ -1174,6 +1175,14 @@ public IView CurrentView
{
MessageBoxEx.Show("Internal error");
}
+
+ if (iView is FlowDocumentView flow)
+ {
+ flow.ReportCreated -= this.OnReportCreated;
+ flow.ReportCreated += this.OnReportCreated;
+ flow.Closed -= new EventHandler(this.OnFlowDocumentViewClosed);
+ flow.Closed += new EventHandler(this.OnFlowDocumentViewClosed);
+ }
}
IView o = this.cacheViews[typeof(T)];
@@ -1181,7 +1190,6 @@ public IView CurrentView
return (T)o;
}
-
///
/// Gets or Creates a single view and makes it the current active view
///
@@ -3388,6 +3396,10 @@ object IServiceProvider.GetService(Type service)
{
return this.TransactionView.ViewModel;
}
+ else if (service == typeof(FlowDocumentView))
+ {
+ return this.GetOrCreateView();
+ }
return null;
}
@@ -3517,17 +3529,27 @@ private void OnFlowDocumentViewClosed(object sender, EventArgs e)
this.SetCurrentView();
}
+ private ReportEventHandler reportHandler;
+
+
+ private void OnReportCreated(object sender, IReport e)
+ {
+ using (this.reportHandler)
+ {
+ // dispose previous report handler.
+ }
+
+ this.reportHandler = new ReportEventHandler(this, e);
+ }
+
private void OnCommandNetWorth(object sender, ExecutedRoutedEventArgs e)
{
this.SaveViewStateOfCurrentView();
FlowDocumentView view = this.SetCurrentView();
view.SetValue(System.Windows.Automation.AutomationProperties.AutomationIdProperty, "ReportNetworth");
- view.Closed -= new EventHandler(this.OnFlowDocumentViewClosed);
- view.Closed += new EventHandler(this.OnFlowDocumentViewClosed);
HelpService.SetHelpKeyword(view, "Reports/NetworthReport/");
- NetWorthReport report = new NetWorthReport(view, this.myMoney, this.cache);
- report.SecurityDrillDown += this.OnReportDrillDown;
- report.CashBalanceDrillDown += this.OnReportCashDrillDown;
+ NetWorthReport report = new NetWorthReport() { ServiceProvider = this };
+ this.OnReportCreated(this, report);
this.GenerateReport(report);
}
@@ -3536,12 +3558,9 @@ private void OnCommandFutureBills(object sender, ExecutedRoutedEventArgs e)
this.SaveViewStateOfCurrentView();
FlowDocumentView view = this.SetCurrentView();
view.SetValue(System.Windows.Automation.AutomationProperties.AutomationIdProperty, "FutureBillsReport");
- view.Closed -= new EventHandler(this.OnFlowDocumentViewClosed);
- view.Closed += new EventHandler(this.OnFlowDocumentViewClosed);
HelpService.SetHelpKeyword(view, "Reports/FutureBillsReport/");
- FutureBillsReport report = new FutureBillsReport(this.myMoney);
- report.PayeeSelected += this.OnReportPayeeSelected;
- report.CategorySelected += this.OnReportCategorySelected;
+ FutureBillsReport report = new FutureBillsReport() { ServiceProvider = this };
+ this.OnReportCreated(this, report);
this.GenerateReport(report);
}
@@ -3577,11 +3596,13 @@ private void ViewInvestmentPortfolio()
this.SaveViewStateOfCurrentView();
FlowDocumentView view = this.SetCurrentView();
view.SetValue(System.Windows.Automation.AutomationProperties.AutomationIdProperty, "ReportPortfolio");
- view.Closed -= new EventHandler(this.OnFlowDocumentViewClosed);
- view.Closed += new EventHandler(this.OnFlowDocumentViewClosed);
HelpService.SetHelpKeyword(view, "Reports/InvestmentPortfolio/");
- PortfolioReport report = new PortfolioReport(view, this.myMoney, null, this, DateTime.Now);
- report.DrillDown += this.OnReportDrillDown;
+ PortfolioReport report = new PortfolioReport()
+ {
+ ServiceProvider = this,
+ ReportDate = DateTime.Now
+ };
+ this.OnReportCreated(this, report);
this.GenerateReport(report);
}
@@ -3591,10 +3612,14 @@ private void OnReportDrillDown(object sender, SecurityGroup e)
this.SaveViewStateOfCurrentView();
FlowDocumentView view = this.SetCurrentView();
view.SetValue(System.Windows.Automation.AutomationProperties.AutomationIdProperty, "ReportPortfolio");
- view.Closed -= new EventHandler(this.OnFlowDocumentViewClosed);
- view.Closed += new EventHandler(this.OnFlowDocumentViewClosed);
HelpService.SetHelpKeyword(view, "Reports/InvestmentPortfolio/");
- PortfolioReport report = new PortfolioReport(view, this.myMoney, this, e.Date, e);
+ PortfolioReport report = new PortfolioReport()
+ {
+ ServiceProvider = this,
+ ReportDate = e.Date,
+ SelectedGroup = e
+ };
+ this.OnReportCreated(this, report);
this.GenerateReport(report);
}
@@ -3604,10 +3629,14 @@ private void OnReportCashDrillDown(object sender, AccountGroup e)
this.SaveViewStateOfCurrentView();
FlowDocumentView view = this.SetCurrentView();
view.SetValue(System.Windows.Automation.AutomationProperties.AutomationIdProperty, "ReportPortfolio");
- view.Closed -= new EventHandler(this.OnFlowDocumentViewClosed);
- view.Closed += new EventHandler(this.OnFlowDocumentViewClosed);
HelpService.SetHelpKeyword(view, "Reports/InvestmentPortfolio/");
- PortfolioReport report = new PortfolioReport(view, this.myMoney, this, e.Date, e);
+ PortfolioReport report = new PortfolioReport()
+ {
+ ServiceProvider = this,
+ ReportDate = e.Date,
+ AccountGroup = e
+ };
+ this.OnReportCreated(this, report);
this.GenerateReport(report);
}
@@ -3616,10 +3645,9 @@ private void OnTaxReport(object sender, ExecutedRoutedEventArgs e)
this.SaveViewStateOfCurrentView();
FlowDocumentView view = this.SetCurrentView();
view.SetValue(System.Windows.Automation.AutomationProperties.AutomationIdProperty, "ReportTaxes");
- view.Closed -= new EventHandler(this.OnFlowDocumentViewClosed);
- view.Closed += new EventHandler(this.OnFlowDocumentViewClosed);
HelpService.SetHelpKeyword(view, "Reports/TaxReport/");
- TaxReport report = new TaxReport(view, this.myMoney, this.databaseSettings.FiscalYearStart);
+ TaxReport report = new TaxReport() { FiscalYearStart = this.databaseSettings.FiscalYearStart, ServiceProvider = this };
+ this.OnReportCreated(this, report);
this.GenerateReport(report);
}
@@ -3628,10 +3656,9 @@ private void OnCommandW2Report(object sender, ExecutedRoutedEventArgs e)
this.SaveViewStateOfCurrentView();
FlowDocumentView view = this.SetCurrentView();
view.SetValue(System.Windows.Automation.AutomationProperties.AutomationIdProperty, "ReportW2");
- view.Closed -= new EventHandler(this.OnFlowDocumentViewClosed);
- view.Closed += new EventHandler(this.OnFlowDocumentViewClosed);
HelpService.SetHelpKeyword(view, "Reports/W2Report/");
- W2Report report = new W2Report(view, this.myMoney, this, this.databaseSettings.FiscalYearStart);
+ W2Report report = new W2Report() { ServiceProvider = this, FiscalYearStart = this.databaseSettings.FiscalYearStart };
+ this.OnReportCreated(this, report);
this.GenerateReport(report);
}
@@ -3646,9 +3673,8 @@ private void OnCommandReportCashFlow(object sender, ExecutedRoutedEventArgs e)
this.SaveViewStateOfCurrentView();
FlowDocumentView view = this.SetCurrentView();
view.SetValue(System.Windows.Automation.AutomationProperties.AutomationIdProperty, "ReportCashFlow");
- view.Closed -= new EventHandler(this.OnFlowDocumentViewClosed);
- view.Closed += new EventHandler(this.OnFlowDocumentViewClosed);
- CashFlowReport report = new CashFlowReport(view, this.myMoney, this, this.databaseSettings.FiscalYearStart);
+ CashFlowReport report = new CashFlowReport() { ServiceProvider = this, FiscalYearStart = this.databaseSettings.FiscalYearStart };
+ this.OnReportCreated(this, report);
this.GenerateReport(report);
}
@@ -3657,11 +3683,10 @@ private void OnCommandReportUnaccepted(object sender, ExecutedRoutedEventArgs e)
this.SaveViewStateOfCurrentView();
FlowDocumentView view = this.SetCurrentView();
view.SetValue(System.Windows.Automation.AutomationProperties.AutomationIdProperty, "ReportUnaccepted");
- view.Closed -= new EventHandler(this.OnFlowDocumentViewClosed);
- view.Closed += new EventHandler(this.OnFlowDocumentViewClosed);
var pixelsPerDip = VisualTreeHelper.GetDpi(this).PixelsPerDip;
FlowDocumentReportWriter writer = new FlowDocumentReportWriter(view.DocumentViewer.Document, pixelsPerDip);
- UnacceptedReport report = new UnacceptedReport(this.myMoney);
+ UnacceptedReport report = new UnacceptedReport() { ServiceProvider = this };
+ this.OnReportCreated(this, report);
this.GenerateReport(report);
}
@@ -4530,11 +4555,15 @@ private void ShowChangeInfo(string previousVersion, XDocument changeList, bool i
this.SaveViewStateOfCurrentView();
FlowDocumentView view = this.SetCurrentView();
view.SetValue(System.Windows.Automation.AutomationProperties.AutomationIdProperty, "ReportUpdates");
- view.Closed -= new EventHandler(this.OnFlowDocumentViewClosed);
- view.Closed += new EventHandler(this.OnFlowDocumentViewClosed);
HelpService.SetHelpKeyword(view, "Basics/Updates/");
- ChangeInfoFormatter report = new ChangeInfoFormatter(view, installButton, previousVersion, changeList);
- report.InstallButtonClick += this.OnInstallButtonClick;
+ ChangeInfoReport report = new ChangeInfoReport()
+ {
+ InstallButton = installButton,
+ PreviousVersion = previousVersion,
+ Document = changeList,
+ ServiceProvider = this
+ };
+ this.OnReportCreated(this, report);
_ = view.Generate(report);
}
}
@@ -4704,5 +4733,157 @@ private void OnStockQuoteServiceOptions(object sender, ExecutedRoutedEventArgs e
#endregion
+ #region Report Events
+
+ ///
+ /// This class breaks the circular dependency between reports and this MainWindow by inserting
+ /// the window as a weak reference. This way reports will be garbage collected properly.
+ ///
+ class ReportEventHandler : IDisposable
+ {
+ WeakReference windowRef;
+ IReport report;
+ private bool disposedValue;
+
+ internal ReportEventHandler(MainWindow window, IReport e)
+ {
+ this.windowRef = new WeakReference(window);
+ this.report = e;
+
+ var view = window.GetOrCreateView();
+ view.PreviewMouseLeftButtonUp -= this.OnFlowViewPreviewMouseLeftButtonUp;
+ view.PreviewMouseLeftButtonUp += this.OnFlowViewPreviewMouseLeftButtonUp;
+ view.Unloaded += (s, e) =>
+ {
+ view.PreviewMouseLeftButtonUp -= this.OnFlowViewPreviewMouseLeftButtonUp;
+ };
+
+ if (e is NetWorthReport report)
+ {
+ report.SecurityDrillDown -= this.OnReportDrillDown;
+ report.CashBalanceDrillDown -= this.OnReportCashDrillDown;
+ report.SecurityDrillDown += this.OnReportDrillDown;
+ report.CashBalanceDrillDown += this.OnReportCashDrillDown;
+ }
+ else if (e is FutureBillsReport bills)
+ {
+ bills.PayeeSelected -= this.OnReportPayeeSelected;
+ bills.CategorySelected -= this.OnReportCategorySelected;
+ bills.PayeeSelected += this.OnReportPayeeSelected;
+ bills.CategorySelected += this.OnReportCategorySelected;
+ }
+ else if (e is PortfolioReport portfolio)
+ {
+ portfolio.DrillDown -= this.OnReportDrillDown;
+ portfolio.DrillDown += this.OnReportDrillDown;
+ }
+ else if (e is ChangeInfoReport changes)
+ {
+ changes.InstallButtonClick -= this.OnInstallButtonClick;
+ changes.InstallButtonClick += this.OnInstallButtonClick;
+ }
+ }
+
+
+ private void OnFlowViewPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
+ {
+ if (windowRef.TryGetTarget(out MainWindow target))
+ {
+ this.report.OnMouseLeftButtonClick(sender, e);
+ }
+ }
+
+ private void OnReportDrillDown(object sender, SecurityGroup e)
+ {
+ if (windowRef.TryGetTarget(out MainWindow target))
+ {
+ target.OnReportDrillDown(sender, e);
+ }
+ }
+
+ private void OnReportCashDrillDown(object sender, AccountGroup e)
+ {
+ if (windowRef.TryGetTarget(out MainWindow target))
+ {
+ target.OnReportCashDrillDown(sender, e);
+ }
+ }
+
+ private void OnReportCategorySelected(object sender, Category c)
+ {
+ if (windowRef.TryGetTarget(out MainWindow target))
+ {
+ target.OnReportCategorySelected(sender, c);
+ }
+ }
+
+ private void OnReportPayeeSelected(object sender, Payee p)
+ {
+ if (windowRef.TryGetTarget(out MainWindow target))
+ {
+ target.OnReportPayeeSelected(sender, p);
+ }
+ }
+
+ private void OnInstallButtonClick(object sender, EventArgs e)
+ {
+ if (windowRef.TryGetTarget(out MainWindow target))
+ {
+ target.OnInstallButtonClick(sender, e);
+ }
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (this.windowRef != null && windowRef.TryGetTarget(out MainWindow window))
+ {
+ var view = window.GetOrCreateView();
+ view.PreviewMouseLeftButtonUp -= this.OnFlowViewPreviewMouseLeftButtonUp;
+ }
+
+ if (this.report != null)
+ {
+ var report = this.report;
+
+ if (report is NetWorthReport networth)
+ {
+ networth.SecurityDrillDown -= this.OnReportDrillDown;
+ networth.CashBalanceDrillDown -= this.OnReportCashDrillDown;
+ }
+ else if (report is FutureBillsReport bills)
+ {
+ bills.PayeeSelected -= this.OnReportPayeeSelected;
+ bills.CategorySelected -= this.OnReportCategorySelected;
+ }
+ else if (report is PortfolioReport portfolio)
+ {
+ portfolio.DrillDown -= this.OnReportDrillDown;
+ }
+ else if (report is ChangeInfoReport changes)
+ {
+ changes.InstallButtonClick -= this.OnInstallButtonClick;
+ }
+ }
+
+ this.report = null;
+ this.windowRef = null;
+ }
+
+ // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
+ ~ReportEventHandler()
+ {
+ // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
+ this.Dispose(disposing: false);
+ }
+
+ public void Dispose()
+ {
+ // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
+ this.Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+ }
+
+ #endregion
}
}
diff --git a/Source/WPF/MyMoney/Reports/CashFlowReport.cs b/Source/WPF/MyMoney/Reports/CashFlowReport.cs
index 184408ee..ba4cffba 100644
--- a/Source/WPF/MyMoney/Reports/CashFlowReport.cs
+++ b/Source/WPF/MyMoney/Reports/CashFlowReport.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
@@ -16,130 +17,96 @@
namespace Walkabout.Reports
{
- internal class CashFlowCell
- {
- internal List Data; // or splits
- internal decimal Value;
- }
-
- internal class CashFlowColumns
+ //=========================================================================================
+ public class CashFlowReport : Report
{
- private readonly Dictionary columns = new Dictionary();
+ private MyMoney myMoney;
+ private bool byYear;
+ private int fiscalYearStart;
+ private DateTime startDate;
+ private DateTime endDate;
+ private Dictionary byCategory;
+ private Dictionary monthMap;
+ private List columns;
- public void AddValue(string key, Transaction data, decimal amount)
+ public CashFlowReport()
{
- CashFlowCell cell;
- this.columns.TryGetValue(key, out cell);
- if (cell == null)
- {
- cell = new CashFlowCell();
- cell.Data = new List();
- this.columns[key] = cell;
- }
- cell.Value += amount;
- if (data != null)
- {
- cell.Data.Add(data);
- }
+ this.startDate = new DateTime(DateTime.Now.Year, 1, 1);
+ this.byYear = true;
+ this.endDate = this.startDate.AddYears(1);
+ this.startDate = this.startDate.AddYears(-4); // show 5 years by default.
}
- public CashFlowCell GetCell(string key)
+ ~CashFlowReport()
{
- CashFlowCell cell = null;
- if (!this.columns.TryGetValue(key, out cell))
- {
- cell = new CashFlowCell();
- }
- return cell;
+ Debug.WriteLine("CashFlowReport disposed!");
}
- public decimal GetValue(string key)
+ public int FiscalYearStart
{
- CashFlowCell cell;
- this.columns.TryGetValue(key, out cell);
- if (cell != null)
+ get => this.fiscalYearStart;
+ set
{
- return cell.Value;
+ this.fiscalYearStart = value;
+ this.startDate = new DateTime(DateTime.Now.Year, this.fiscalYearStart + 1, 1);
+ if (this.startDate > DateTime.Today)
+ {
+ this.startDate = this.startDate.AddYears(-1);
+ }
}
- return 0;
}
- public List GetData(string key)
+ public override void OnSiteChanged()
{
- CashFlowCell cell;
- this.columns.TryGetValue(key, out cell);
- if (cell != null)
- {
- return cell.Data;
- }
- return new List();
+ this.myMoney = (MyMoney)this.ServiceProvider.GetService(typeof(MyMoney));
}
- public List GetOrderedValues(IEnumerable columnKeys)
+ class CashFlowReportState : IReportState
{
- List result = new List();
- foreach (string name in columnKeys)
+ public int FiscalYearStart { get; set; }
+ public DateTime StartDate { get; set; }
+ public DateTime EndDate { get; set; }
+
+ public CashFlowReportState()
{
- result.Add(this.GetValue(name));
}
- return result;
- }
-
- public int Count { get { return this.columns.Count; } }
- }
-
- //=========================================================================================
- public class CashFlowReport : Report
- {
- private readonly FlowDocumentView view;
- private readonly MyMoney myMoney;
- private bool byYear;
- private readonly int fiscalYearStart;
- private DateTime startDate;
- private DateTime endDate;
- private Dictionary byCategory;
- private Dictionary monthMap;
- private List columns;
- private readonly IServiceProvider serviceProvider;
- public CashFlowReport(FlowDocumentView view, MyMoney money, IServiceProvider sp, int fiscalYearStart)
- {
- this.myMoney = money;
- this.fiscalYearStart = fiscalYearStart;
- this.startDate = new DateTime(DateTime.Now.Year, 1, 1);
- this.byYear = true;
- if (this.fiscalYearStart > 0)
+ public Type GetReportType()
{
- this.startDate = new DateTime(DateTime.Now.Year, this.fiscalYearStart + 1, 1);
- if (this.startDate > DateTime.Today)
- {
- this.startDate = this.startDate.AddYears(-1);
- }
+ return typeof(CashFlowReport);
}
+ }
- this.endDate = this.startDate.AddYears(1);
- this.startDate = this.startDate.AddYears(-4); // show 5 years by default.
- this.view = view;
- this.serviceProvider = sp;
- view.Unloaded += (s, e) =>
+ public override IReportState GetState()
+ {
+ return new CashFlowReportState()
{
- this.view.PreviewMouseLeftButtonUp -= this.OnPreviewMouseLeftButtonUp;
+ FiscalYearStart = this.fiscalYearStart,
+ StartDate = this.startDate,
+ EndDate = this.endDate
};
- view.Loaded += (s, e) =>
+ }
+
+ public override void ApplyState(IReportState state)
+ {
+ if (state is CashFlowReportState cashFlowReportState)
{
- view.PreviewMouseLeftButtonUp -= this.OnPreviewMouseLeftButtonUp;
- view.PreviewMouseLeftButtonUp += this.OnPreviewMouseLeftButtonUp;
- };
+ this.FiscalYearStart = cashFlowReportState.FiscalYearStart;
+ this.startDate = cashFlowReportState.StartDate;
+ this.endDate = cashFlowReportState.EndDate;
+ }
}
- private void OnPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
+
+ public override void OnMouseLeftButtonClick(object sender, MouseButtonEventArgs e)
{
- Point pos = e.GetPosition(this.view);
+ var view = (FlowDocumentView)sender;
+ Point pos = e.GetPosition(view);
if (this.mouseDownCell != null && Math.Abs(this.downPos.X - pos.X) < 5 && Math.Abs(this.downPos.Y - pos.Y) < 5)
{
// navigate to show the cell.Data rows.
- IViewNavigator nav = this.serviceProvider.GetService(typeof(IViewNavigator)) as IViewNavigator;
+ IViewNavigator nav = this.ServiceProvider.GetService(typeof(IViewNavigator)) as IViewNavigator;
nav.ViewTransactions(this.mouseDownCell.Data);
}
}
@@ -200,11 +167,6 @@ private bool IsInvestment(Category c)
return c.Type == CategoryType.Investments;
}
- public void Regenerate()
- {
- _ = this.view.Generate(this);
- }
-
public override Task Generate(IReportWriter writer)
{
this.byCategory = new Dictionary();
@@ -378,6 +340,12 @@ private void OnByYearMonthChanged(object sender, SelectionChangedEventArgs e)
this.Regenerate();
}
+ public void Regenerate()
+ {
+ var view = (FlowDocumentView)this.ServiceProvider.GetService(typeof(FlowDocumentView));
+ _ = view.Generate(this);
+ }
+
private Button CreateExportReportButton()
{
Button button = this.CreateReportButton("Icons/Excel.png", "Export", "Export .csv spreadsheet file format");
@@ -591,9 +559,10 @@ private void WriteRow(IReportWriter writer, bool header, bool addExpanderCell, s
private void OnReportCellMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
+ var view = (FlowDocumentView)this.ServiceProvider.GetService(typeof(FlowDocumentView));
Paragraph p = (Paragraph)sender;
this.mouseDownCell = (CashFlowCell)p.Tag;
- this.downPos = e.GetPosition(this.view);
+ this.downPos = e.GetPosition(view);
}
@@ -652,6 +621,79 @@ private void GenerateCsvGroup(StreamWriter writer, Dictionary Data; // or splits
+ internal decimal Value;
+ }
+
+ internal class CashFlowColumns
+ {
+ private readonly Dictionary columns = new Dictionary();
+
+ public void AddValue(string key, Transaction data, decimal amount)
+ {
+ CashFlowCell cell;
+ this.columns.TryGetValue(key, out cell);
+ if (cell == null)
+ {
+ cell = new CashFlowCell();
+ cell.Data = new List();
+ this.columns[key] = cell;
+ }
+ cell.Value += amount;
+ if (data != null)
+ {
+ cell.Data.Add(data);
+ }
+ }
+
+ public CashFlowCell GetCell(string key)
+ {
+ CashFlowCell cell = null;
+ if (!this.columns.TryGetValue(key, out cell))
+ {
+ cell = new CashFlowCell();
+ }
+ return cell;
+ }
+
+ public decimal GetValue(string key)
+ {
+ CashFlowCell cell;
+ this.columns.TryGetValue(key, out cell);
+ if (cell != null)
+ {
+ return cell.Value;
+ }
+ return 0;
+ }
+
+ public List GetData(string key)
+ {
+ CashFlowCell cell;
+ this.columns.TryGetValue(key, out cell);
+ if (cell != null)
+ {
+ return cell.Data;
+ }
+ return new List();
+ }
+
+ public List GetOrderedValues(IEnumerable columnKeys)
+ {
+ List result = new List();
+ foreach (string name in columnKeys)
+ {
+ result.Add(this.GetValue(name));
+ }
+ return result;
+ }
+
+ public int Count { get { return this.columns.Count; } }
+ }
+
}
}
diff --git a/Source/WPF/MyMoney/Reports/FutureBillsReport.cs b/Source/WPF/MyMoney/Reports/FutureBillsReport.cs
index 8b3b1b39..91f12b2a 100644
--- a/Source/WPF/MyMoney/Reports/FutureBillsReport.cs
+++ b/Source/WPF/MyMoney/Reports/FutureBillsReport.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Data;
+using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
@@ -16,7 +17,7 @@ namespace Walkabout.Reports
///
public class FutureBillsReport : Report
{
- private readonly MyMoney myMoney;
+ private MyMoney myMoney;
private const int ALLOWED_MISSED_PAYMENTS = 2;
internal struct PaymentKey
@@ -102,8 +103,6 @@ internal class Payments
internal const double AmountSensitivity = 0.1; // % stderr
internal const double TimeSensitivity = 0.5; // % stderr on date
- private List transactions;
-
public Payee Payee { get; internal set; }
public Category Category { get; internal set; }
@@ -285,9 +284,27 @@ public Payments()
}
}
- public FutureBillsReport(MyMoney money)
+ public FutureBillsReport()
+ {
+ }
+
+ ~FutureBillsReport()
+ {
+ Debug.WriteLine("FutureBillsReport disposed!");
+ }
+
+ public override void OnSiteChanged()
+ {
+ this.myMoney = (MyMoney)this.ServiceProvider.GetService(typeof(MyMoney));
+ }
+
+ public override IReportState GetState()
+ {
+ return new SimpleReportState(typeof(FutureBillsReport));
+ }
+
+ public override void ApplyState(IReportState state)
{
- this.myMoney = money;
}
public override Task Generate(IReportWriter writer)
@@ -466,6 +483,7 @@ public override void Export(string filename)
{
throw new NotImplementedException();
}
+
}
diff --git a/Source/WPF/MyMoney/Reports/IReport.cs b/Source/WPF/MyMoney/Reports/IReport.cs
index 9694da57..37a16fcd 100644
--- a/Source/WPF/MyMoney/Reports/IReport.cs
+++ b/Source/WPF/MyMoney/Reports/IReport.cs
@@ -1,15 +1,45 @@
-using System.Threading.Tasks;
+using System;
+using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
+using Walkabout.Views;
namespace Walkabout.Interfaces.Reports
{
public interface IReport
{
+ IServiceProvider ServiceProvider { get; set; }
+
Task Generate(IReportWriter writer);
void Export(string filename);
+
+ IReportState GetState();
+
+ void ApplyState(IReportState state);
+
+ void OnMouseLeftButtonClick(object sender, MouseButtonEventArgs e);
+ }
+
+ public interface IReportState
+ {
+ Type GetReportType();
+ }
+
+ public class SimpleReportState : IReportState
+ {
+ Type type;
+
+ public SimpleReportState(Type reportType)
+ {
+ this.type = reportType;
+ }
+
+ public virtual Type GetReportType()
+ {
+ return this.type;
+ }
}
public enum ReportInterval
diff --git a/Source/WPF/MyMoney/Reports/NetWorthReport.cs b/Source/WPF/MyMoney/Reports/NetWorthReport.cs
index 788e8316..746fbff2 100644
--- a/Source/WPF/MyMoney/Reports/NetWorthReport.cs
+++ b/Source/WPF/MyMoney/Reports/NetWorthReport.cs
@@ -1,6 +1,7 @@
using LovettSoftware.Charts;
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
@@ -20,28 +21,63 @@ namespace Walkabout.Reports
//=========================================================================================
public class NetWorthReport : Report
{
- private readonly FlowDocumentView view;
- private readonly MyMoney myMoney;
+ private MyMoney myMoney;
private readonly Random rand = new Random(Environment.TickCount);
private readonly byte minRandColor, maxRandColor;
private DateTime reportDate;
- private readonly StockQuoteCache cache;
+ private StockQuoteCache cache;
private bool generating;
private bool filterOutClosedAccounts = false;
public event EventHandler SecurityDrillDown;
public event EventHandler CashBalanceDrillDown;
- public NetWorthReport(FlowDocumentView view, MyMoney money, StockQuoteCache cache)
+ public NetWorthReport()
{
- this.view = view;
- this.myMoney = money;
- this.cache = cache;
this.reportDate = DateTime.Now;
this.minRandColor = 20;
this.maxRandColor = ("" + AppTheme.Instance.GetTheme()).Contains("Dark") ? (byte)128 : (byte)200;
}
+ ~NetWorthReport()
+ {
+ Debug.WriteLine("NetWorthReport disposed!");
+ }
+
+ public override void OnSiteChanged()
+ {
+ this.myMoney = (MyMoney)this.ServiceProvider.GetService(typeof(MyMoney));
+ this.cache = (StockQuoteCache)this.ServiceProvider.GetService(typeof(StockQuoteCache));
+ }
+
+ class NetworthReportState : IReportState
+ {
+ public DateTime ReportDate { get; set; }
+
+ public NetworthReportState(DateTime reportDate)
+ {
+ this.ReportDate = reportDate;
+ }
+
+ public Type GetReportType()
+ {
+ return typeof(NetWorthReport);
+ }
+ }
+
+ public override IReportState GetState()
+ {
+ return new NetworthReportState(reportDate);
+ }
+
+ public override void ApplyState(IReportState state)
+ {
+ if (state is NetworthReportState networthReportState)
+ {
+ this.reportDate = networthReportState.ReportDate;
+ }
+ }
+
public override async Task Generate(IReportWriter writer)
{
this.generating = true;
@@ -298,11 +334,17 @@ private void Picker_SelectedDateChanged(object sender, SelectionChangedEventArgs
{
this.reportDate = picker.SelectedDate.Value;
this.filterOutClosedAccounts = this.reportDate >= DateTime.Today;
- _ = this.view.Generate(this);
+ this.Regenerate();
}
}
}
+ private void Regenerate()
+ {
+ var view = (FlowDocumentView)this.ServiceProvider.GetService(typeof(FlowDocumentView));
+ _ = view.Generate(this);
+ }
+
private void OnPieSliceClicked(object sender, ChartDataValue e)
{
if (e.UserData is SecurityGroup g)
diff --git a/Source/WPF/MyMoney/Reports/PortfolioReport.cs b/Source/WPF/MyMoney/Reports/PortfolioReport.cs
index 6c137a40..440abeb3 100644
--- a/Source/WPF/MyMoney/Reports/PortfolioReport.cs
+++ b/Source/WPF/MyMoney/Reports/PortfolioReport.cs
@@ -1,6 +1,7 @@
using LovettSoftware.Charts;
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
@@ -13,6 +14,7 @@
using Walkabout.Interfaces.Reports;
using Walkabout.Interfaces.Views;
using Walkabout.StockQuotes;
+using Walkabout.Taxes;
using Walkabout.Utilities;
using Walkabout.Views;
@@ -21,18 +23,16 @@ namespace Walkabout.Reports
//=========================================================================================
public class PortfolioReport : Report
{
- private readonly MyMoney myMoney;
- private readonly Account account;
+ private MyMoney myMoney;
+ private Account account;
private FlowDocumentReportWriter flowwriter;
private CostBasisCalculator calc;
- private readonly IServiceProvider serviceProvider;
- private readonly FlowDocumentView view;
private Paragraph mouseDownPara;
private Point downPos;
private DateTime reportDate;
- private readonly StockQuoteCache cache;
+ private StockQuoteCache cache;
private SecurityGroup selectedGroup;
- private readonly AccountGroup accountGroup;
+ private AccountGroup accountGroup;
private readonly Random rand = new Random(Environment.TickCount);
private bool generating;
@@ -41,62 +41,104 @@ public class PortfolioReport : Report
///
/// Create new PortfolioReport
///
- /// The FlowDocumentView we are generating the report in
- /// The money database
- /// Optional account for single account portfolio
- /// Required to access additional services
- /// The date to compute the portfolio balances to
- public PortfolioReport(FlowDocumentView view, MyMoney money, Account account, IServiceProvider serviceProvider, DateTime asOfDate)
- {
- this.myMoney = money;
- this.account = account;
- this.serviceProvider = serviceProvider;
- this.view = view;
- this.reportDate = asOfDate;
- this.cache = (StockQuoteCache)serviceProvider.GetService(typeof(StockQuoteCache));
- view.PreviewMouseLeftButtonUp -= this.OnPreviewMouseLeftButtonUp;
- view.PreviewMouseLeftButtonUp += this.OnPreviewMouseLeftButtonUp;
- view.Unloaded += (s, e) =>
- {
- this.view.PreviewMouseLeftButtonUp -= this.OnPreviewMouseLeftButtonUp;
- };
+ public PortfolioReport()
+ {
}
- ///
- /// Create new PortfolioReport for a given SecurityGroup we are drilling into from the Networth Report, like "Taxable Mutual Funds".
- ///
- public PortfolioReport(FlowDocumentView view, MyMoney money, IServiceProvider serviceProvider, DateTime asOfDate, SecurityGroup a) :
- this(view, money, null, serviceProvider, asOfDate)
+ ~PortfolioReport()
{
- this.selectedGroup = a;
+ Debug.WriteLine("PortfolioReport disposed!");
}
- ///
- /// Create new PortfolioReport for a given AccountGroup, this will show just the cash balances of these accounts.
- ///
- public PortfolioReport(FlowDocumentView view, MyMoney money, IServiceProvider serviceProvider, DateTime asOfDate, AccountGroup a) :
- this(view, money, null, serviceProvider, asOfDate)
+
+ public Account Account
{
- this.accountGroup = a;
+ get => this.account;
+ set => this.account = value;
}
- private void OnPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
+ public AccountGroup AccountGroup
{
- Point pos = e.GetPosition(this.view);
+ get => this.accountGroup;
+ set => this.accountGroup = value;
+ }
+
+ public SecurityGroup SelectedGroup
+ {
+ get => this.selectedGroup;
+ set => this.selectedGroup = value;
+ }
+
+ public DateTime ReportDate
+ {
+ get => reportDate;
+ set => reportDate = value;
+ }
+
+ public override void OnSiteChanged()
+ {
+ this.cache = (StockQuoteCache)this.ServiceProvider.GetService(typeof(StockQuoteCache));
+ this.myMoney = (MyMoney)this.ServiceProvider.GetService(typeof(MyMoney));
+ }
+
+ class PortfolioReportState : IReportState
+ {
+ public DateTime ReportDate { get; set; }
+ public Account Account { get; set; }
+ public AccountGroup AccountGroup { get; set; }
+ public SecurityGroup SelectedGroup { get; set; }
+
+ public PortfolioReportState()
+ {
+ }
+
+ public Type GetReportType()
+ {
+ return typeof(PortfolioReport);
+ }
+ }
+
+ public override IReportState GetState()
+ {
+ return new PortfolioReportState()
+ {
+ ReportDate = this.reportDate,
+ Account = this.account,
+ AccountGroup = this.accountGroup,
+ SelectedGroup = this.selectedGroup,
+ };
+ }
+
+ public override void ApplyState(IReportState state)
+ {
+ if (state is PortfolioReportState taxReportState)
+ {
+ this.reportDate = taxReportState.ReportDate;
+ this.account = taxReportState.Account;
+ this.accountGroup = taxReportState.AccountGroup;
+ this.selectedGroup = taxReportState.SelectedGroup;
+ }
+ }
+
+ public override void OnMouseLeftButtonClick(object sender, MouseButtonEventArgs e)
+ {
+ var view = (FlowDocumentView)this.ServiceProvider.GetService(typeof(FlowDocumentView));
+ Point pos = e.GetPosition(view);
if (this.mouseDownPara != null && Math.Abs(this.downPos.X - pos.X) < 5 && Math.Abs(this.downPos.Y - pos.Y) < 5)
{
string name = (string)this.mouseDownPara.Tag;
// navigate to show the cell.Data rows.
- IViewNavigator nav = this.serviceProvider.GetService(typeof(IViewNavigator)) as IViewNavigator;
+ IViewNavigator nav = this.ServiceProvider.GetService(typeof(IViewNavigator)) as IViewNavigator;
nav.ViewTransactionsBySecurity(this.myMoney.Securities.FindSecurity(name, false));
}
}
private void OnReportCellMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
+ var view = (FlowDocumentView)this.ServiceProvider.GetService(typeof(FlowDocumentView));
this.mouseDownPara = (Paragraph)sender;
- this.downPos = e.GetPosition(this.view);
+ this.downPos = e.GetPosition(view);
}
private decimal totalMarketValue;
@@ -356,12 +398,18 @@ private void Picker_SelectedDateChanged(object sender, SelectionChangedEventArgs
{
this.accountGroup.Date = newDate;
}
- _ = this.view.Generate(this);
+ this.Regenerate();
}
}
}
}
+ void Regenerate()
+ {
+ var view = (FlowDocumentView)this.ServiceProvider.GetService(typeof(FlowDocumentView));
+ _ = view.Generate(this);
+ }
+
private string GetSecurityTypeCaption(SecurityType st)
{
string caption = "";
diff --git a/Source/WPF/MyMoney/Reports/Reports.cs b/Source/WPF/MyMoney/Reports/Reports.cs
index 9b50f2ad..40c55796 100644
--- a/Source/WPF/MyMoney/Reports/Reports.cs
+++ b/Source/WPF/MyMoney/Reports/Reports.cs
@@ -8,6 +8,7 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
+using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Walkabout.Data;
@@ -20,9 +21,29 @@ public abstract class Report : IReport
{
private Currency currency;
private CultureInfo currencyCulture;
+ private IServiceProvider serviceProvider;
+
+ public IServiceProvider ServiceProvider
+ {
+ get => serviceProvider;
+ set {
+ serviceProvider = value;
+ this.OnSiteChanged();
+ }
+ }
+
+ public virtual void OnSiteChanged() { }
+
+ public abstract IReportState GetState();
+
+ public abstract void ApplyState(IReportState state);
public abstract Task Generate(IReportWriter writer);
+ public virtual void OnMouseLeftButtonClick(object sender, MouseButtonEventArgs e)
+ {
+ }
+
public virtual void Export(string filename)
{
throw new NotImplementedException();
diff --git a/Source/WPF/MyMoney/Reports/TaxReport.cs b/Source/WPF/MyMoney/Reports/TaxReport.cs
index 6184e99a..e1987fdb 100644
--- a/Source/WPF/MyMoney/Reports/TaxReport.cs
+++ b/Source/WPF/MyMoney/Reports/TaxReport.cs
@@ -20,21 +20,74 @@ namespace Walkabout.Reports
//=========================================================================================
public class TaxReport : Report
{
- private readonly FlowDocumentView view;
- private readonly MyMoney money;
+ private MyMoney money;
private DateTime startDate;
private DateTime endDate;
private bool consolidateOnDateSold;
private bool capitalGainsOnly;
- private readonly int fiscalYearStart;
+ private int fiscalYearStart;
private const string FiscalPrefix = "FY ";
- public TaxReport(FlowDocumentView view, MyMoney money, int fiscalYearStart)
+ public TaxReport()
{
- this.fiscalYearStart = fiscalYearStart;
- this.view = view;
this.SetStartDate(DateTime.Now.Year);
- this.money = money;
+ }
+
+ ~TaxReport()
+ {
+ Debug.WriteLine("TaxReport disposed!");
+ }
+
+ public int FiscalYearStart
+ {
+ get => this.fiscalYearStart;
+ set {
+ this.fiscalYearStart = value;
+ }
+ }
+
+ public override void OnSiteChanged()
+ {
+ this.money = (MyMoney)this.ServiceProvider.GetService(typeof(MyMoney));
+ }
+
+ class TaxReportState : IReportState
+ {
+ public int FiscalYearStart { get; set; }
+ public bool CapitalGainsOnly { get; set; }
+ public bool ConsolidateOnDateSold { get; set; }
+ public int TaxYear { get; set; }
+
+ public TaxReportState()
+ {
+ }
+
+ public Type GetReportType()
+ {
+ return typeof(TaxReport);
+ }
+ }
+
+ public override IReportState GetState()
+ {
+ return new TaxReportState()
+ {
+ FiscalYearStart = this.fiscalYearStart,
+ CapitalGainsOnly = this.capitalGainsOnly,
+ ConsolidateOnDateSold = this.consolidateOnDateSold,
+ TaxYear = this.startDate.Year
+ };
+ }
+
+ public override void ApplyState(IReportState state)
+ {
+ if (state is TaxReportState taxReportState)
+ {
+ this.FiscalYearStart = taxReportState.FiscalYearStart;
+ this.capitalGainsOnly = taxReportState.CapitalGainsOnly;
+ this.consolidateOnDateSold = taxReportState.ConsolidateOnDateSold;
+ this.SetStartDate(taxReportState.TaxYear);
+ }
}
private void SetStartDate(int year)
@@ -57,7 +110,6 @@ public override Task Generate(IReportWriter writer)
{
FlowDocumentReportWriter fwriter = (FlowDocumentReportWriter)writer;
-
writer.WriteHeading("Tax Report For ");
var (firstYear, lastYear) = this.money.Transactions.GetTaxYearRange(this.fiscalYearStart);
@@ -137,7 +189,8 @@ public override Task Generate(IReportWriter writer)
}
this.GenerateCapitalGains(writer);
- FlowDocument document = this.view.DocumentViewer.Document;
+ var view = (FlowDocumentView)this.ServiceProvider.GetService(typeof(FlowDocumentView));
+ FlowDocument document = view.DocumentViewer.Document;
document.Blocks.InsertAfter(document.Blocks.FirstBlock, new BlockUIContainer(this.CreateExportTxfButton()));
return Task.CompletedTask;
}
@@ -183,11 +236,18 @@ private void WriteHeaders(IReportWriter writer)
writer.EndRow();
}
+
+ private void Renerate()
+ {
+ var view = (FlowDocumentView)this.ServiceProvider.GetService(typeof(FlowDocumentView));
+ _ = view.Generate(this);
+ }
+
private void OnCapitalGainsOnlyChanged(object sender, RoutedEventArgs e)
{
CheckBox checkBox = (CheckBox)sender;
this.capitalGainsOnly = checkBox.IsChecked == true;
- _ = this.view.Generate(this);
+ this.Renerate();
}
private void OnConsolidateComboSelectionChanged(object sender, SelectionChangedEventArgs e)
@@ -195,7 +255,7 @@ private void OnConsolidateComboSelectionChanged(object sender, SelectionChangedE
ComboBox box = (ComboBox)sender;
int index = box.SelectedIndex;
this.consolidateOnDateSold = index == 1;
- _ = this.view.Generate(this);
+ this.Renerate();
}
private void OnYearChanged(object sender, SelectionChangedEventArgs e)
@@ -209,7 +269,7 @@ private void OnYearChanged(object sender, SelectionChangedEventArgs e)
if (int.TryParse(label, out int year))
{
this.SetStartDate(year);
- _ = this.view.Generate(this);
+ this.Renerate();
}
}
diff --git a/Source/WPF/MyMoney/Reports/UnacceptedReport.cs b/Source/WPF/MyMoney/Reports/UnacceptedReport.cs
index 32726252..27945f04 100644
--- a/Source/WPF/MyMoney/Reports/UnacceptedReport.cs
+++ b/Source/WPF/MyMoney/Reports/UnacceptedReport.cs
@@ -1,4 +1,5 @@
using System;
+using System.Diagnostics;
using System.Threading.Tasks;
using Walkabout.Data;
using Walkabout.Interfaces.Reports;
@@ -10,11 +11,29 @@ namespace Walkabout.Reports
///
public class UnacceptedReport : Report
{
- private readonly MyMoney myMoney;
+ private MyMoney myMoney;
- public UnacceptedReport(MyMoney money)
+ public UnacceptedReport()
+ {
+ }
+
+ ~UnacceptedReport()
+ {
+ Debug.WriteLine("UnacceptedReport disposed!");
+ }
+
+ public override void OnSiteChanged()
+ {
+ this.myMoney = (MyMoney)this.ServiceProvider.GetService(typeof(MyMoney));
+ }
+
+ public override IReportState GetState()
+ {
+ return new SimpleReportState(typeof(UnacceptedReport));
+ }
+
+ public override void ApplyState(IReportState state)
{
- this.myMoney = money;
}
public override Task Generate(IReportWriter writer)
diff --git a/Source/WPF/MyMoney/Reports/W2Report.cs b/Source/WPF/MyMoney/Reports/W2Report.cs
index 25522cbf..70e8da8c 100644
--- a/Source/WPF/MyMoney/Reports/W2Report.cs
+++ b/Source/WPF/MyMoney/Reports/W2Report.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
@@ -17,33 +18,73 @@ namespace Walkabout.Taxes
// This class prepares an estimated W2 from the splits found in paycheck deposits.
public class W2Report : Report
{
- private readonly FlowDocumentView view;
- private readonly MyMoney myMoney;
+ private MyMoney myMoney;
private DateTime startDate;
private DateTime endDate;
- private readonly IServiceProvider serviceProvider;
private Point downPos;
- private readonly int fiscalYearStart;
+ private int fiscalYearStart;
private Category selectedCategory;
- private readonly TaxCategoryCollection taxCategories;
+ private TaxCategoryCollection taxCategories;
private Dictionary> transactionsByCategory;
private const string FiscalPrefix = "FY ";
- public W2Report(FlowDocumentView view, MyMoney money, IServiceProvider sp, int fiscalYearStart)
+ public W2Report()
{
- this.myMoney = money;
- this.fiscalYearStart = fiscalYearStart;
- this.view = view;
- this.serviceProvider = sp;
- view.PreviewMouseLeftButtonUp -= this.OnPreviewMouseLeftButtonUp;
- view.PreviewMouseLeftButtonUp += this.OnPreviewMouseLeftButtonUp;
- view.Unloaded += (s, e) =>
+ }
+
+ ~W2Report()
+ {
+ Debug.WriteLine("W2Report disposed!");
+ }
+
+ public int FiscalYearStart
+ {
+ get => this.fiscalYearStart;
+ set {
+ this.fiscalYearStart = value;
+
+ }
+ }
+
+ public override void OnSiteChanged()
+ {
+ this.taxCategories = new TaxCategoryCollection();
+ this.transactionsByCategory = null;
+ this.myMoney = (MyMoney)this.ServiceProvider.GetService(typeof(MyMoney));
+ }
+
+ class W2ReportState : IReportState
+ {
+ public int FiscalYearStart { get; set; }
+ public DateTime StartDate { get; set; }
+
+ public W2ReportState()
+ {
+ }
+
+ public Type GetReportType()
+ {
+ return typeof(W2Report);
+ }
+ }
+
+ public override IReportState GetState()
+ {
+ return new W2ReportState()
{
- view.PreviewMouseLeftButtonUp -= this.OnPreviewMouseLeftButtonUp;
+ FiscalYearStart = this.fiscalYearStart,
+ StartDate = this.startDate,
};
- this.taxCategories = new TaxCategoryCollection();
}
+ public override void ApplyState(IReportState state)
+ {
+ if (state is W2ReportState taxReportState)
+ {
+ this.FiscalYearStart = taxReportState.FiscalYearStart;
+ this.SetStartDate(taxReportState.StartDate);
+ }
+ }
private void SetStartDate(DateTime date)
{
@@ -65,14 +106,15 @@ private void SetStartDate(DateTime date)
this.endDate = this.startDate.AddYears(1);
}
- private void OnPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
+ public override void OnMouseLeftButtonClick(object sender, MouseButtonEventArgs e)
{
- Point pos = e.GetPosition(this.view);
+ var view = (FlowDocumentView)this.ServiceProvider.GetService(typeof(FlowDocumentView));
+ Point pos = e.GetPosition(view);
if (Math.Abs(this.downPos.X - pos.X) < 5 && Math.Abs(this.downPos.Y - pos.Y) < 5)
{
// navigate to show the cell.Data rows.
- IViewNavigator nav = this.serviceProvider.GetService(typeof(IViewNavigator)) as IViewNavigator;
+ IViewNavigator nav = this.ServiceProvider.GetService(typeof(IViewNavigator)) as IViewNavigator;
List transactions = null;
if (this.selectedCategory != null && this.transactionsByCategory.TryGetValue(this.selectedCategory, out transactions))
{
@@ -83,7 +125,8 @@ private void OnPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
public void Regenerate()
{
- _ = this.view.Generate(this);
+ var view = (FlowDocumentView)this.ServiceProvider.GetService(typeof(FlowDocumentView));
+ _ = view.Generate(this);
}
private bool Summarize(Dictionary byCategory, Transaction t)
@@ -374,9 +417,10 @@ private string GetCategoryCaption(Category c)
private void OnReportCellMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
+ var view = (FlowDocumentView)this.ServiceProvider.GetService(typeof(FlowDocumentView));
Paragraph p = (Paragraph)sender;
this.selectedCategory = p.Tag as Category;
- this.downPos = e.GetPosition(this.view);
+ this.downPos = e.GetPosition(view);
}
diff --git a/Source/WPF/MyMoney/Setup/ChangeInfoFormatter.cs b/Source/WPF/MyMoney/Setup/ChangeInfoReport.cs
similarity index 71%
rename from Source/WPF/MyMoney/Setup/ChangeInfoFormatter.cs
rename to Source/WPF/MyMoney/Setup/ChangeInfoReport.cs
index 9c939bb7..94197d64 100644
--- a/Source/WPF/MyMoney/Setup/ChangeInfoFormatter.cs
+++ b/Source/WPF/MyMoney/Setup/ChangeInfoReport.cs
@@ -1,10 +1,12 @@
using System;
+using System.Diagnostics;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media.Imaging;
using System.Xml.Linq;
+using Walkabout.Data;
using Walkabout.Interfaces.Reports;
using Walkabout.Reports;
using Walkabout.Utilities;
@@ -12,12 +14,13 @@
namespace Walkabout.Setup
{
- internal class ChangeInfoFormatter : Report
+ internal class ChangeInfoReport
+ : Report
{
- private readonly string previousVersion;
- private readonly XDocument doc;
- private readonly FlowDocumentView view;
- private readonly bool installButton;
+ private string previousVersion;
+ private XDocument doc;
+ private FlowDocumentView view;
+ private bool installButton;
public event EventHandler InstallButtonClick;
@@ -29,12 +32,68 @@ private void OnInstallButtonClick()
}
}
- public ChangeInfoFormatter(FlowDocumentView view, bool addInstallButton, string previousVersion, XDocument doc)
+ public ChangeInfoReport()
{
- this.previousVersion = previousVersion;
- this.doc = doc;
- this.view = view;
- this.installButton = addInstallButton;
+ }
+
+ ~ChangeInfoReport()
+ {
+ Debug.WriteLine("ChangeInfoReport disposed!");
+ }
+
+
+ public string PreviousVersion
+ {
+ get => previousVersion;
+ set => previousVersion = value;
+ }
+
+ public bool InstallButton
+ {
+ get => installButton;
+ set => installButton = value;
+ }
+ public XDocument Document
+ {
+ get => doc;
+ set => doc = value;
+ }
+
+ public override void OnSiteChanged()
+ {
+ this.view = (FlowDocumentView)this.ServiceProvider.GetService(typeof(FlowDocumentView));
+ }
+
+ public class ChangeInfoReportState : IReportState
+ {
+ public string PreviousVersion { get; set; }
+ public bool InstallButton { get; set; }
+ public XDocument Document { get; set; }
+ public ChangeInfoReportState() { }
+
+ public Type GetReportType() {
+ return typeof(ChangeInfoReport);
+ }
+ }
+
+ public override IReportState GetState()
+ {
+ return new ChangeInfoReportState()
+ {
+ PreviousVersion = this.previousVersion,
+ InstallButton = this.installButton,
+ Document = this.doc
+ };
+ }
+
+ public override void ApplyState(IReportState state)
+ {
+ if (state is ChangeInfoReportState cs)
+ {
+ this.previousVersion = cs.PreviousVersion;
+ this.installButton = cs.InstallButton;
+ this.doc = cs.Document;
+ }
}
///
diff --git a/Source/WPF/MyMoney/Views/FlowDocumentView.xaml.cs b/Source/WPF/MyMoney/Views/FlowDocumentView.xaml.cs
index 8e6f9113..8e74a431 100644
--- a/Source/WPF/MyMoney/Views/FlowDocumentView.xaml.cs
+++ b/Source/WPF/MyMoney/Views/FlowDocumentView.xaml.cs
@@ -154,16 +154,26 @@ public object SelectedRow
public ViewState ViewState
{
- get { return new ReportViewState(this.report); }
+ get { return new ReportViewState(this.report.GetState()); }
set
{
- if (value is ReportViewState r)
+ if (value is ReportViewState s)
{
- _ = this.Generate(r.report);
+ var type = s.ReportState.GetReportType();
+ var report = (IReport)Activator.CreateInstance(type);
+ report.ServiceProvider = this.serviceProvider;
+ report.ApplyState(s.ReportState);
+ if (ReportCreated != null)
+ {
+ ReportCreated(this, report);
+ }
+ _ = this.Generate(report);
}
}
}
+ public event EventHandler ReportCreated;
+
public ViewState DeserializeViewState(System.Xml.XmlReader reader)
{
return new ViewState();
@@ -302,11 +312,11 @@ private void ResetExpandAllToggleButton()
///
internal class ReportViewState : ViewState
{
- public IReport report;
+ public IReportState ReportState { get; private set; }
- public ReportViewState(IReport report)
+ public ReportViewState(IReportState reportState)
{
- this.report = report;
+ this.ReportState = reportState;
}
}
diff --git a/Source/WPF/MyMoney/Views/TransactionsView.xaml.cs b/Source/WPF/MyMoney/Views/TransactionsView.xaml.cs
index c4a18613..00309999 100644
--- a/Source/WPF/MyMoney/Views/TransactionsView.xaml.cs
+++ b/Source/WPF/MyMoney/Views/TransactionsView.xaml.cs
@@ -9,6 +9,7 @@
using System.Globalization;
using System.IO;
using System.Linq;
+using System.Security.Principal;
using System.Text;
using System.Windows;
using System.Windows.Automation;
@@ -2298,7 +2299,12 @@ private void UpdatePortfolio(Account account)
this.SetActiveAccount(account, null, null, null, null);
// if we are reconciling then show the positions held at statement date so the stock balances can be reconciled also.
DateTime reportDate = this.IsReconciling ? this.GetReconiledExclusiveEndDate() : DateTime.Now;
- PortfolioReport report = new PortfolioReport(view, this.myMoney, account, this.ServiceProvider, reportDate);
+ PortfolioReport report = new PortfolioReport()
+ {
+ ServiceProvider = this.ServiceProvider,
+ ReportDate = reportDate,
+ Account = account
+ };
report.DrillDown += this.OnReportDrillDown;
_ = view.Generate(report);
this.portfolioReport = report;
@@ -2315,7 +2321,12 @@ private void OnReportDrillDown(object sender, SecurityGroup e)
FlowDocumentView view = this.InvestmentPortfolioView;
HelpService.SetHelpKeyword(view, "Reports/InvestmentPortfolio/");
DateTime reportDate = this.IsReconciling ? this.GetReconiledExclusiveEndDate() : DateTime.Now;
- PortfolioReport report = new PortfolioReport(view, this.myMoney, this.ServiceProvider, reportDate, e);
+ PortfolioReport report = new PortfolioReport()
+ {
+ ServiceProvider = this.ServiceProvider,
+ ReportDate = reportDate,
+ SelectedGroup = e
+ };
_ = view.Generate(report);
this.FireAfterViewStateChanged(this.SelectedRowId);
}
diff --git a/Source/WPF/Version/VersionMaster.txt b/Source/WPF/Version/VersionMaster.txt
index 95f92f23..80cbfbc9 100644
--- a/Source/WPF/Version/VersionMaster.txt
+++ b/Source/WPF/Version/VersionMaster.txt
@@ -1 +1 @@
-2.1.0.20
\ No newline at end of file
+2.1.0.21
\ No newline at end of file