using FastReport.Utils;
using System;
namespace FastReport.Engine
{
public partial class ReportEngine
{
#region Fields
private ReportPage page;
private float columnStartY;
private string pageNameForRecalc;
#endregion Fields
#region Private Methods
private DataBand FindDeepmostDataBand(ReportPage page)
{
DataBand result = null;
foreach (Base c in page.AllObjects)
{
if (c is DataBand)
result = c as DataBand;
}
return result;
}
private void RunReportPage(ReportPage page)
{
this.page = page;
InitReprint();
pageNameForRecalc = null;
this.page.OnStartPage(EventArgs.Empty);
bool previousPage = StartFirstPage();
OnStateChanged(this.page, EngineState.ReportPageStarted);
OnStateChanged(this.page, EngineState.PageStarted);
DataBand keepSummaryBand = FindDeepmostDataBand(page);
if (keepSummaryBand != null)
keepSummaryBand.KeepSummary = true;
if (this.page.IsManualBuild)
this.page.OnManualBuild(EventArgs.Empty);
else
RunBands(page.Bands);
OnStateChanged(this.page, EngineState.PageFinished);
OnStateChanged(this.page, EngineState.ReportPageFinished);
EndLastPage();
//recalculate unlimited
if (page.UnlimitedHeight || page.UnlimitedWidth)
{
PreparedPages.ModifyPageSize(page.Name);
if (previousPage && pageNameForRecalc != null)
PreparedPages.ModifyPageSize(pageNameForRecalc);
}
//recalculate unlimited
this.page.OnFinishPage(EventArgs.Empty);
if (this.page.BackPage)
{
PreparedPages.InterleaveWithBackPage(PreparedPages.CurPage);
}
}
private bool CalcVisibleExpression(string expression)
{
bool result = true;
object expressionObj = null;
// Calculate expressions with TotalPages only on FinalPass.
if (!expression.Contains("TotalPages") || (Report.DoublePass && FinalPass))
{
expressionObj = Report.Calc(Code.CodeUtils.FixExpressionWithBrackets(expression));
}
if (expressionObj != null && expressionObj is bool)
{
if (!expression.Contains("TotalPages"))
{
result = (bool)expressionObj;
}
else if (FirstPass)
{
result = true;
}
else
{
result = (bool)expressionObj;
}
}
return result;
}
private void RunReportPages()
{
#if TIMETRIAL
if (new DateTime($YEAR, $MONTH, $DAY) < System.DateTime.Now)
throw new Exception("The trial version is now expired!");
#endif
for (int i = 0; i < Report.Pages.Count; i++)
{
ReportPage page = Report.Pages[i] as ReportPage;
// Calc and apply visible expression if needed.
if (page != null && !String.IsNullOrEmpty(page.VisibleExpression))
{
page.Visible = CalcVisibleExpression(page.VisibleExpression);
}
if (page != null && page.Visible && page.Subreport == null)
RunReportPage(page);
if (Report.Aborted)
break;
}
}
private void RunBands(BandCollection bands)
{
for (int i = 0; i < bands.Count; i++)
{
BandBase band = bands[i];
if (band is DataBand)
RunDataBand(band as DataBand);
else if (band is GroupHeaderBand)
RunGroup(band as GroupHeaderBand);
if (Report.Aborted)
break;
}
}
private void ShowPageHeader()
{
ShowBand(page.PageHeader);
}
private void ShowPageFooter(bool startPage)
{
if (!FirstPass &&
CurPage == TotalPages - 1 &&
page.PageFooter != null &&
(page.PageFooter.PrintOn & PrintOn.LastPage) > 0 &&
(page.PageFooter.PrintOn & PrintOn.FirstPage) == 0 &&
startPage)
{
ShiftLastPage();
}
else
ShowBand(page.PageFooter);
}
private bool StartFirstPage()
{
page.InitializeComponents();
CurX = 0;
CurY = 0;
curColumn = 0;
if (page.ResetPageNumber)
ResetLogicalPageNumber();
bool previousPage = page.PrintOnPreviousPage && PreparedPages.Count > 0;
// check that previous page has the same size
if (previousPage)
{
using (ReportPage page0 = PreparedPages.GetPage(PreparedPages.Count - 1))
{
if (page0.PaperWidth == this.page.PaperWidth)
{
if (page0.UnlimitedWidth == this.page.UnlimitedWidth)
{
previousPage = true;
if (this.page.UnlimitedWidth)
pageNameForRecalc = page0.Name;
}
else
{
previousPage = false;
}
}
else if (page0.UnlimitedWidth && this.page.UnlimitedWidth)
{
previousPage = true;
pageNameForRecalc = page0.Name;
}
else
{
previousPage = false;
}
if (previousPage)
{
if (page0.PaperHeight == this.page.PaperHeight)
{
if (page0.UnlimitedHeight == this.page.UnlimitedHeight)
{
previousPage = true;
if (this.page.UnlimitedHeight)
pageNameForRecalc = page0.Name;
}
else
{
previousPage = false;
}
}
else if (page0.UnlimitedHeight && this.page.UnlimitedHeight)
{
previousPage = true;
}
else
{
previousPage = false;
}
}
}
}
// update CurY or add new page
if (previousPage)
CurY = PreparedPages.GetLastY();
else
{
PreparedPages.AddPage(page);
if (page.StartOnOddPage && (CurPage % 2) == 1)
PreparedPages.AddPage(page);
}
// page numbers
if (isFirstReportPage)
firstReportPage = CurPage;
if (isFirstReportPage && previousPage)
IncLogicalPageNumber();
isFirstReportPage = false;
OutlineRoot();
AddPageOutline();
// show report title and page header
if (previousPage)
ShowBand(page.ReportTitle);
else
{
if (page.Overlay != null)
ShowBand(page.Overlay);
if (page.TitleBeforeHeader)
{
ShowBand(page.ReportTitle);
ShowPageHeader();
}
else
{
ShowPageHeader();
ShowBand(page.ReportTitle);
}
}
// show column header
columnStartY = CurY;
ShowBand(page.ColumnHeader);
// calculate CurX before starting column event depending on Right to Left or Left to Right layout
if (Config.RightToLeft)
{
CurX = page.Columns.Positions[page.Columns.Positions.Count - 1] * Units.Millimeters;
}
else
{
CurX = 0;
}
// start column event
OnStateChanged(page, EngineState.ColumnStarted);
ShowProgress();
return previousPage;
}
private void EndLastPage()
{
// end column event
OnStateChanged(page, EngineState.ColumnFinished);
if (page.ReportSummary != null)
{
// do not show column footer here! It's a special case and is handled in the ShowBand.
ShowBand(page.ReportSummary);
}
else
{
ShowBand(page.ColumnFooter);
}
ShowPageFooter(false);
OutlineRoot();
page.FinalizeComponents();
}
internal void EndColumn()
{
EndColumn(true);
}
private void EndColumn(bool showColumnFooter)
{
// end column event
OnStateChanged(page, EngineState.ColumnFinished);
// check keep
if (keeping)
CutObjects();
ShowReprintFooters();
if (showColumnFooter)
ShowBand(page.ColumnFooter);
curColumn++;
if (curColumn >= page.Columns.Count)
curColumn = 0;
// apply Right to Left layot if needed
if (Config.RightToLeft)
{
curX = page.Columns.Positions[page.Columns.Count - curColumn - 1] * Units.Millimeters;
}
else
{
curX = curColumn == 0 ? 0 : page.Columns.Positions[curColumn] * Units.Millimeters;
}
if (CurColumn == 0)
{
EndPage();
}
else
{
StartColumn();
}
// end keep
if (keeping)
PasteObjects();
}
private void StartColumn()
{
curY = columnStartY;
ShowBand(page.ColumnHeader);
ShowReprintHeaders();
// start column event
OnStateChanged(page, EngineState.ColumnStarted);
}
private void EndPage()
{
EndPage(true);
}
private void StartPage()
{
// apply Right to Left layout if needed
if (Config.RightToLeft)
{
CurX = page.Columns.Positions[page.Columns.Positions.Count - 1] * Units.Millimeters;
}
else
{
CurX = 0;
}
CurY = 0;
curColumn = 0;
PreparedPages.AddPage(page);
AddPageOutline();
if (page.Overlay != null)
ShowBand(page.Overlay);
ShowPageHeader();
OnStateChanged(page, EngineState.PageStarted);
columnStartY = CurY;
StartColumn();
ShowProgress();
}
#endregion Private Methods
#region Internal Methods
internal void EndPage(bool startPage)
{
OnStateChanged(page, EngineState.PageFinished);
ShowPageFooter(startPage);
if (pagesLimit > 0 && PreparedPages.Count >= pagesLimit)
Report.Abort();
if (Report.MaxPages > 0 && PreparedPages.Count >= Report.MaxPages)
Report.Abort();
if (startPage)
StartPage();
}
#endregion Internal Methods
#region Public Methods
///
/// Starts a new page.
///
public void StartNewPage()
{
EndPage();
}
///
/// Starts a new column.
///
public void StartNewColumn()
{
EndColumn();
}
#endregion Public Methods
}
}