/*
i-net software provides programming examples for illustration only, without warranty
either expressed or implied, including, but not limited to, the implied warranties
of merchantability and/or fitness for a particular purpose. This programming example
assumes that you are familiar with the programming language being demonstrated and
the tools used to create and debug procedures. i-net software support professionals
can help explain the functionality of a particular procedure, but they will not modify
these examples to provide added functionality or construct procedures to meet your
specific needs.
© i-net software 1998-2013
*/
using System;
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;
using System.Threading;
using Inet.Viewer.Resources;
using Inet.Viewer.WinForms;
namespace Inet.Viewer.Data
{
///
/// Progress implementation for printing a report.
///
public class PrintProgress : Progress
{
private PrintDocument printDoc;
private int currentPage;
private ReportDataCache reportDataCache;
private int pageCount;
private PrinterSettings printerSettings;
///
/// Creates a print progress for the specified render data.
///
/// the report to print
/// printing settings
/// a delegate which will be called on failures during the progress
public PrintProgress(IRenderData renderData, PrinterSettings printerSettings, Action errorDelegate) :
this(new ReportDataCache(renderData), printerSettings, errorDelegate)
{
}
///
/// Creates a print progress for the specified ReportDataCache instance.
///
/// the report to print as ReportDataCache instance
/// printing settings
/// a delegate which will be called on failures during the progress
internal PrintProgress(ReportDataCache reportDataCache, PrinterSettings printerSettings, Action errorDelegate) :
base(errorDelegate, ProgressType.Print)
{
this.reportDataCache = reportDataCache;
this.printerSettings = printerSettings;
printDoc = new PrintDocument();
printDoc.PrinterSettings = printerSettings;
printDoc.QueryPageSettings += new QueryPageSettingsEventHandler(printDoc_QueryPageSettings);
printDoc.PrintPage += new PrintPageEventHandler(printDoc_PrintPage);
}
///
/// Gets or sets the report info instance. When the report and the page info instances are set both, no
/// additional request to the report data cache is needed before printing.
///
internal ReportInfo ReportInfo
{
get;
set;
}
///
/// Gets or sets the page info instance. When the report and the page info instances are set both, no
/// additional request to the report data cache is needed before printing.
///
internal PageInfo PageInfo
{
get;
set;
}
///
/// Gets or sets the current page of the viewer. Used when the user selects "Current Page" in the
/// printing dialog.
///
internal int CurrentViewPage
{
set;
get;
}
///
protected override void Run()
{
try
{
pageCount = reportDataCache.PageCount();
PrintRange rangeType = printerSettings.PrintRange;
if (rangeType == PrintRange.SomePages)
{
currentPage = printerSettings.FromPage;
}
else if (rangeType == PrintRange.CurrentPage)
{
currentPage = CurrentViewPage;
}
else
{
currentPage = 1;
}
LoadMetaDataIfRequired();
printDoc.DocumentName = ReportInfo.Title;
printDoc.Print();
Status = ProgressStatus.Completed;
}
catch (Exception e)
{
ShowError(e);
}
}
///
/// Called before printing a page. Sets the page settings.
///
/// not used
/// event args which include page settings
private void printDoc_QueryPageSettings(object sender, QueryPageSettingsEventArgs e)
{
e.PageSettings.Margins = PageInfo.PrintMargins;
}
///
/// Called when printing the next page. Does the actual output on the printer graphics.
///
///
///
private void printDoc_PrintPage(object sender, PrintPageEventArgs ev)
{
Graphics2DPainter painter = new Graphics2DPainter(true);
PrinterPageView pageView = new PrinterPageView(ErrorDelegate, reportDataCache, ev);
byte[] pageData = reportDataCache.PageData(currentPage, false);
pageView.Page = currentPage;
PageLoader pLoader = new PageLoader(painter, pageView);
pLoader.PaintPage(pageData);
currentPage++;
PrintRange rangeType = ev.PageSettings.PrinterSettings.PrintRange;
if (rangeType == PrintRange.SomePages)
{
ev.HasMorePages = currentPage <= Math.Min( pageCount, ev.PageSettings.PrinterSettings.ToPage);
}
else if (rangeType == PrintRange.CurrentPage)
{
ev.HasMorePages = false;
}
else
{
ev.HasMorePages = currentPage <= pageCount;
}
ev.Cancel = Status == ProgressStatus.Canceled;
}
///
public override string Name
{
get { return strings.Print; }
}
///
public override void Cancel()
{
Status = ProgressStatus.Canceled;
}
///
/// Updates the default page settings of the printer settings. This will change the PrinterSettings
/// instance specified via the constructor when creating this progress.
/// If no meta data (ReportInfo / PageInfo) was set manually, the required properties are loaded
/// directly from the underlying IRenderData instance.
/// Since this method may invoke blocking I/O operations, it should not be called form a UI thread.
///
public void UpdatePageSettings()
{
LoadMetaDataIfRequired();
printerSettings.DefaultPageSettings.Landscape = PageInfo.PageAlign == (int)PageOrientation.Landscape;
printerSettings.DefaultPageSettings.Margins = PageInfo.PrintMargins;
}
///
/// Loads the meta data if not set yet.
///
private void LoadMetaDataIfRequired()
{
if (ReportInfo == null || PageInfo == null)
{
// meta data not set yet => parse the first page
PageMetaReceiver pageMetaReceiver = new PageMetaReceiver();
PageLoader loader = new PageLoader(null, pageMetaReceiver);
loader.Data = reportDataCache.PageData(1, false);
loader.ReadTokens();
if (pageMetaReceiver.Error != null)
{
ShowError(pageMetaReceiver.Error);
return;
}
ReportInfo = pageMetaReceiver.ReportInfo;
PageInfo = pageMetaReceiver.PageInfo;
}
}
}
}