using System.IO;
using System.Windows;
using System.Windows.Controls;
using FastReport;
using FastReport.Export;
using FastReport.Export.BIFF8;
using FastReport.Export.Html;
using FastReport.Export.Image;
using FastReport.Export.Pdf;
using FastReport.Export.RichText;
using FastReport.Export.Text;
using InABox.Clients;
using InABox.Core;
using InABox.WPF;
using Button = System.Windows.Controls.Button;
using Image = System.Windows.Controls.Image;
using SaveFileDialog = Microsoft.Win32.SaveFileDialog;
using System;
using InABox.Wpf;
using TextBox = System.Windows.Controls.TextBox;
using InABox.Core.Reports;
using ICSharpCode.AvalonEdit.Highlighting;
using System.Drawing;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Threading;
using FastReport.Design;
using Syncfusion.Windows.Controls.RichTextBoxAdv;
namespace InABox.Wpf.Reports
{
///
/// Interaction logic for PreviewWindow.xaml
///
public partial class PreviewWindow : ThemableWindow
{
private Report _report;
private readonly ReportTemplate _template;
private readonly DataModel _model;
private bool modelIsPopulated;
public Action? SaveTemplate { get; set; } = null;
public PreviewWindow(ReportTemplate template, DataModel model)
{
InitializeComponent();
_template = template;
_model = model;
modelIsPopulated = false;
PrintButton.Content = ImageUtils.CreatePreviewWindowButtonContent("Print",Wpf.Resources.print);
SavePDFButton.Content = ImageUtils.CreatePreviewWindowButtonContent("Save PDF", Wpf.Resources.save);
SaveRTFButton.Content = ImageUtils.CreatePreviewWindowButtonContent("Save RTF", Wpf.Resources.save);
SaveExcelButton.Content = ImageUtils.CreatePreviewWindowButtonContent("Save Excel", Wpf.Resources.save);
foreach (var def in ReportUtils.ExportDefinitions)
{
var button = new Button();
if (def.Control != null)
button.Content = def.Control;
else
button.Content = GetImage(def.Image);
button.VerticalAlignment = VerticalAlignment.Top;
button.Click += (o, e) =>
{
var data = ExportReport(def.Type);
def.Action.Invoke(model, data);
};
Toolbar.Items.Insert(Toolbar.Items.IndexOf(ExportSeparator), button);
}
//EmailButton.Content = GetImage(Wpf.Resources.email);
FirstButton.Content = ImageUtils.CreatePreviewWindowButtonContent("First",Wpf.Resources.first);
BackButton.Content = ImageUtils.CreatePreviewWindowButtonContent("Back",Wpf.Resources.back);
NextButton.Content = ImageUtils.CreatePreviewWindowButtonContent("Next",Wpf.Resources.next);
LastButton.Content = ImageUtils.CreatePreviewWindowButtonContent("Last",Wpf.Resources.last);
ZoomInButton.Content = ImageUtils.CreatePreviewWindowButtonContent("Zoom In",Wpf.Resources.zoomin);
ZoomOutButton.Content = ImageUtils.CreatePreviewWindowButtonContent("Zoom Out",Wpf.Resources.zoomout);
DesignButton.Content = ImageUtils.CreatePreviewWindowButtonContent("Design",Wpf.Resources.pencil);
Loaded += PreviewWindow_Loaded;
Editor.TextChanged += Editor_TextChanged;
Designer.InnerDesigner.cmdSave.CustomAction += (sender, args) => SaveReport();
Designer.InnerDesigner.cmdSaveAs.CustomAction += (sender, args) => SaveReportAs();
Designer.InnerDesigner.cmdPreview.CustomAction += (sender, args) => ShowPreview();
Designer.InnerDesigner.AskSave = false;
}
private void SaveReportAs()
{
var dialog = new SaveFileDialog();
dialog.Filter = "Report files (*.frx)|*.frx";
dialog.FileName = _template.Name + ".frx";
if (dialog.ShowDialog() == true)
Designer.Report.Save(dialog.FileName);
}
// private void CustomSaveReport(object sender, OpenSaveReportEventArgs e)
// {
// SaveReport();
// }
//
// private void CustomSaveReportAs(object sender, OpenSaveDialogEventArgs e)
// {
// var dialog = new SaveFileDialog();
// dialog.Filter = "Report files (*.frx)|*.frx";
// dialog.FileName = _template.Name + ".frx";
// if (dialog.ShowDialog() == true)
// Designer.Report.Save(dialog.FileName);
// }
//
// private void CustomPreviewReport(object? sender, EventArgs e)
// {
// ShowPreview();
// }
private void Editor_TextChanged(object? sender, EventArgs e)
{
}
public bool IsPreview { get; set; } = true;
public bool ShouldPopulate { get; set; } = true;
public Report Report
{
get => _report;
set
{
_report = value;
Designer.Report = value;
Refresh();
}
}
public bool AllowDesign
{
get => DesignButton.Visibility == Visibility.Visible;
set => DesignButton.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
}
private Image GetImage(Bitmap bitmap)
{
return new Image
{
Source = bitmap.AsBitmapImage(),
Height = 32.0F,
Width = 32.0F,
Margin = new Thickness(10)
};
}
private void DisplayLoading()
{
PreviewGrid.RowDefinitions[1].Height = new GridLength(0);
PreviewGrid.RowDefinitions[2].Height = new GridLength(1, GridUnitType.Star);
DesignButton.IsEnabled = false;
}
private void CloseLoading()
{
PreviewGrid.RowDefinitions[1].Height = new GridLength(1, GridUnitType.Star);
PreviewGrid.RowDefinitions[2].Height = new GridLength(0);
DesignButton.IsEnabled = true;
}
private void SetupReport(Action action)
{
DisplayLoading();
Task.Run(() =>
{
try
{
_report ??= ReportUtils.SetupReport(_template, _model, ShouldPopulate && !modelIsPopulated);
return null;
}
catch (Exception e)
{
Logger.Send(LogType.Error,"",$"SetupReport() returned an error!\n{e.Message}\n{e.StackTrace}");
return e.Message;
}
}).ContinueWith((s) =>
{
try
{
if (s.Result == null)
{
Dispatcher.BeginInvoke(() =>
{
try
{
Designer.Report ??= _report;
action();
CloseLoading();
}
catch (Exception e)
{
MessageWindow.ShowError("Some errors were found in this report.", e.Message, "Errors in report");
CloseLoading();
ShowDesigner();
}
});
}
else
{
Dispatcher.BeginInvoke(() =>ShowEditor(s.Result));
}
}
catch (Exception e)
{
Logger.Send(LogType.Error,"",$"An Error occurred while loading the report window!\n{e.Message}\n{e.StackTrace}");
Dispatcher.BeginInvoke(() =>ShowEditor(e.Message));
}
}, TaskScheduler.FromCurrentSynchronizationContext());
}
private void ShowPreview()
{
MainGrid.RowDefinitions[0].Height = new GridLength(1, GridUnitType.Star);
MainGrid.RowDefinitions[1].Height = new GridLength(0);
MainGrid.RowDefinitions[2].Height = new GridLength(0);
Title = string.Format("Report Preview - {0}", _template.Name);
SetupReport(() => Refresh());
}
private void ShowDesigner()
{
MainGrid.RowDefinitions[0].Height = new GridLength(0);
MainGrid.RowDefinitions[1].Height = new GridLength(1, GridUnitType.Star);
MainGrid.RowDefinitions[2].Height = new GridLength(0);
SetupReport(() =>
{
Title = string.Format("Report Designer - {0}", Report.FileName);
//Designer.InnerDesigner.RefreshLayout();
});
}
private void ShowEditor(string err)
{
MainGrid.RowDefinitions[0].Height = new GridLength(0);
MainGrid.RowDefinitions[1].Height = new GridLength(0);
MainGrid.RowDefinitions[2].Height = new GridLength(1, GridUnitType.Star);
Title = string.Format("Edit Report Template - {0}", _template.Name);
Editor.Text = _report?.SaveToString() ?? (String.IsNullOrWhiteSpace(_template.RDL) ? "" : _template.RDL);
Editor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinition("XML");
System.Windows.MessageBox.Show("There was an error loading the report. The raw XML data has been loaded here.\n\nError Message:\n" + (err.Length < 200 ? err : string.Concat(err.AsSpan(0, 200), "...")));
}
private void PreviewWindow_Loaded(object sender, RoutedEventArgs e)
{
if (IsPreview)
{
ShowPreview();
}
else
{
ShowDesigner();
}
}
private class Exporter
{
public Type Export { get; }
public string FileExtension { get; }
public string FileFilter { get; }
public Exporter(Type export, string fileExtension, string fileFilter)
{
Export = export;
FileExtension = fileExtension;
FileFilter = fileFilter;
}
}
private static readonly Dictionary _exporters = new Dictionary
{
{ ReportExportType.PDF, new Exporter(typeof(PDFExport), ".pdf", "PDF Files (*.pdf)|*.pdf") },
{ ReportExportType.HTML, new Exporter(typeof(HTMLExport), ".html", "HTML Files (*.html)|*.html") },
{ ReportExportType.RTF, new Exporter(typeof(RTFExport), ".rtf", "RTF Files (*.rtf)|*.rtf") },
{ ReportExportType.Excel, new Exporter(typeof(Excel2003Document), ".xls", "Excel Files (*.xls)|*.xls") },
{ ReportExportType.Text, new Exporter(typeof(TextExport), ".txt", "Text Files (*.txt)|*.txt") },
{ ReportExportType.Image, new Exporter(typeof(ImageExport), ".jpg", "JPEG Files (*.jpg, *.jpeg)|*.jpg;*.jpeg") }
};
private byte[] ExportReport(ReportExportType type)
{
using var ms = new MemoryStream();
_report.Export(Activator.CreateInstance(_exporters[type].Export) as ExportBase, ms);
return ms.GetBuffer();
}
private void Refresh()
{
_report.WpfPreview = Preview;
// var assyname = typeof(TheArtOfDev.HtmlRenderer.WPF.HtmlRender).Assembly.FullName.Split(',').First();
// AppDomain.CurrentDomain.Load("HtmlRenderer.Ddll");
// AppDomain.CurrentDomain.Load("HtmlRenderer.Wpf.dll");
// _report.AddReferencedAssembly("HtmlRendere");
_report.Prepare();
_report.ShowPrepared();
Preview.Zoom = 1.0F;
}
private void PrintButton_Click(object sender, RoutedEventArgs e)
{
Report.PrintPrepared();
}
private void SaveButton_Click(object sender, RoutedEventArgs e)
{
var exporter = _exporters[(ReportExportType)((Button)sender).Tag];
var dlg = new SaveFileDialog();
dlg.Filter = exporter.FileFilter;
dlg.FileName = Path.ChangeExtension(Report.FileName, exporter.FileExtension);
if (dlg.ShowDialog() == true)
Report.Export(Activator.CreateInstance(exporter.Export) as ExportBase, dlg.FileName);
}
//private void EmailButton_Click(object sender, RoutedEventArgs e)
//{
// String attachment = System.IO.Path.Combine(System.IO.Path.GetTempPath(), System.IO.Path.ChangeExtension(Report.FileName,".pdf"));
// using (new WaitCursor())
// {
// using (var filestream = System.IO.File.Open(attachment, System.IO.FileMode.Create))
// {
// _report.Export(new PDFExport(), filestream);
// filestream.Close();
// }
// }
// //Outlook.Application outlookApp = new Outlook.Application();
// //Outlook.MailItem mailItem = (Outlook.MailItem)outlookApp.CreateItem(Outlook.OlItemType.olMailItem);
// //mailItem.Subject = System.IO.Path.ChangeExtension(Report.FileName,"");
// //mailItem.To = "";
// //mailItem.HTMLBody = "";
// //mailItem.Attachments.Add(attachment, Outlook.OlAttachmentType.olByValue, Type.Missing, Type.Missing);
// //mailItem.Display(false);
//}
private void FirstButton_Click(object sender, RoutedEventArgs e)
{
Preview.First();
}
private void BackButton_Click(object sender, RoutedEventArgs e)
{
Preview.Prior();
}
private void NextButton_Click(object sender, RoutedEventArgs e)
{
Preview.Next();
}
private void LastButton_Click(object sender, RoutedEventArgs e)
{
Preview.Last();
}
private void ZoomInButton_Click(object sender, RoutedEventArgs e)
{
Preview.ZoomIn();
}
private void ZoomOutButton_Click(object sender, RoutedEventArgs e)
{
Preview.ZoomOut();
}
private void SaveReport()
{
_template.RDL = _report.SaveToString();
DoSave(_template);
Designer.Report = _report;
Designer.InnerDesigner.Modified = false;
}
private void DesignButton_Click(object sender, RoutedEventArgs e)
{
ShowDesigner();
}
private void ToolBar_Loaded(object sender, RoutedEventArgs e)
{
var toolBar = sender as ToolBar;
var overflowGrid = toolBar.Template.FindName("OverflowGrid", toolBar) as FrameworkElement;
if (overflowGrid != null) overflowGrid.Visibility = Visibility.Collapsed;
var mainPanelBorder = toolBar.Template.FindName("MainPanelBorder", toolBar) as FrameworkElement;
if (mainPanelBorder != null) mainPanelBorder.Margin = new Thickness();
var grid = toolBar.Template.FindName("Grid", toolBar) as FrameworkElement;
if (grid != null) grid.Margin = new Thickness();
}
private void DoSave(ReportTemplate template)
{
if (SaveTemplate is null)
{
Progress.ShowModal("Saving", p =>
{
new Client().Save(template, "Updated by Designer");
});
}
else
SaveTemplate?.Invoke(template);
}
private void SaveEditorButton_Click(object sender, RoutedEventArgs e)
{
_template.RDL = Editor.Text;
DoSave(_template);
_report = null;
ShowPreview();
}
private void PreviewWindow_OnClosing(object? sender, CancelEventArgs e)
{
if (Designer.InnerDesigner.Modified)
{
var result = MessageWindow.ShowYesNoCancel("There are unsaved changes in this report!\nDo you wish to save them now?","Save Changes");
if (result == MessageWindowResult.Cancel)
{
e.Cancel = true;
return;
}
if (result == MessageWindowResult.Yes)
SaveReport();
}
}
}
}