123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505 |
- using FastReport.Engine;
- using FastReport.Utils;
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Drawing;
- using System.IO;
- using System.Windows.Forms;
- namespace FastReport.Preview
- {
- internal partial class PreparedPage : Component
- {
- #region Fields
- private XmlItem xmlItem;
- private PreparedPages preparedPages;
- private SizeF pageSize;
- private long tempFilePosition;
- private bool uploaded;
- private PreparedPagePostprocessor postprocessor;
- #endregion Fields
- #region Properties
- private Report Report
- {
- get { return preparedPages.Report; }
- }
- private bool UseFileCache
- {
- get { return Report.UseFileCache; }
- }
- public XmlItem Xml
- {
- get { return xmlItem; }
- set
- {
- xmlItem = value;
- value.Parent = null;
- }
- }
- public SizeF PageSize
- {
- get
- {
- if (pageSize.IsEmpty)
- {
- ReCalcSizes();
- }
- return pageSize;
- }
- set
- {
- pageSize = value;
- }
- }
- public int CurPosition
- {
- get { return xmlItem.Count; }
- }
- #endregion Properties
- #region Private Methods
- private bool DoAdd(Base c, XmlItem item)
- {
- if (c == null)
- return false;
- ReportEngine engine = Report.Engine;
- bool isRunning = Report.IsRunning && engine != null;
- if (c is ReportComponentBase)
- {
- if (isRunning && !engine.CanPrint(c as ReportComponentBase))
- return false;
- }
- item = item.Add();
- using (FRWriter writer = new FRWriter(item))
- {
- writer.SerializeTo = SerializeTo.Preview;
- writer.SaveChildren = false;
- writer.BlobStore = preparedPages.BlobStore;
- writer.Write(c);
- }
- if (isRunning)
- engine.AddObjectToProcess(c, item);
- if ((c.Flags & Flags.CanWriteChildren) == 0)
- {
- ObjectCollection childObjects = c.ChildObjects;
- foreach (Base obj in childObjects)
- {
- DoAdd(obj, item);
- }
- }
- return true;
- }
- private Base ReadObject(Base parent, XmlItem item, bool readChildren, FRReader reader)
- {
- string objName = item.Name;
- // try to find the object in the dictionary
- Base obj = preparedPages.Dictionary.GetObject(objName);
- // object not found, objName is type name
- if (obj == null)
- {
- Type type = RegisteredObjects.FindType(objName);
- if (type == null)
- return null;
- obj = Activator.CreateInstance(type) as Base;
- }
- obj.SetRunning(true);
- // read object's properties
- if (!item.IsNullOrEmptyProps())
- {
- // since the BlobStore is shared resource, lock it to avoid problems with multi-thread access.
- // this may happen in the html export that uses several threads to export one report.
- lock (reader.BlobStore)
- {
- reader.Read(obj, item);
- }
- if (obj is TextObject txt)
- ProcessText(txt);
- }
- if (readChildren)
- {
- for (int i = 0; i < item.Count; i++)
- {
- ReadObject(obj, item[i], true, reader);
- }
- }
- obj.Parent = parent;
- return obj;
- }
- private void UpdateUnlimitedPage(Base obj, XmlItem item)
- {
- item.Clear();
- using (FRWriter writer = new FRWriter(item))
- {
- writer.SerializeTo = SerializeTo.Preview;
- writer.SaveChildren = false;
- writer.BlobStore = preparedPages.BlobStore;
- writer.Write(obj);
- }
- foreach (Base child in obj.ChildObjects)
- {
- UpdateUnlimitedPage(child, item.Add());
- }
- }
- #endregion Private Methods
- #region Internal Methods
- internal ReportPage ReadPage(Base parent, XmlItem item, bool readchild, FRReader reader)
- {
- ReportPage page = ReadObject(parent, item, false, reader) as ReportPage;
- if (readchild)
- for (int i = 0; i < item.Count; i++)
- {
- ReadObject(page, item[i], true, reader);
- }
- return page;
- }
- internal ReportPage StartGetPage(int index)
- {
- Load();
- ReportPage page;
- using (FRReader reader = new FRReader(null))
- {
- reader.DeserializeFrom = SerializeTo.Preview;
- reader.ReadChildren = false;
- reader.BlobStore = preparedPages.BlobStore;
- page = ReadPage(null, xmlItem, false, reader);
- if (!(page.UnlimitedHeight || page.UnlimitedWidth))
- {
- page.Dispose();
- page = ReadPage(null, xmlItem, true, reader);
- page.SetReport(preparedPages.Report);
- postprocessor = new PreparedPagePostprocessor();
- postprocessor.Postprocess(page);
- postprocessor = null;
- }
- else
- {
- page.SetReport(preparedPages.Report);
- postprocessor = new PreparedPagePostprocessor();
- postprocessor.PostprocessUnlimited(this, page);
- }
- }
- if (page.MirrorMargins && (index + 1) % 2 == 0)
- {
- float f = page.LeftMargin;
- page.LeftMargin = page.RightMargin;
- page.RightMargin = f;
- }
- return page;
- }
- internal void EndGetPage(ReportPage page)
- {
- if (postprocessor != null) postprocessor = null;
- if (page != null)
- page.Dispose();
- ClearUploadedXml();
- }
- internal IEnumerable<Base> GetPageItems(ReportPage page, bool postprocess)
- {
- if (!(page.UnlimitedHeight || page.UnlimitedWidth))
- {
- foreach (Base child in page.ChildObjects)
- {
- if (postprocess) yield return child;
- else
- using (child)
- yield return child;
- }
- }
- else
- {
- if (Export.ExportBase.HAVE_TO_WORK_WITH_OVERLAY)
- #pragma warning disable CS0162 // Unreachable code detected
- foreach (Base child in page.ChildObjects)
- #pragma warning restore CS0162 // Unreachable code detected
- {
- if (child is OverlayBand)
- yield return child;
- }
- using (FRReader reader = new FRReader(null))
- {
- reader.DeserializeFrom = SerializeTo.Preview;
- reader.ReadChildren = false;
- reader.BlobStore = preparedPages.BlobStore;
- for (int i = 0; i < xmlItem.Count; i++)
- {
- if (postprocess) yield return ReadObject(page, xmlItem[i], true, reader);
- else
- using (Base obj = ReadObject(page, xmlItem[i], true, reader))
- {
- using (Base obj2 = postprocessor.PostProcessBandUnlimitedPage(obj))
- yield return obj2;
- }
- }
- }
- }
- }
- internal string GetName()
- {
- using (FRReader reader = new FRReader(null))
- {
- reader.DeserializeFrom = SerializeTo.Preview;
- reader.ReadChildren = false;
- reader.BlobStore = preparedPages.BlobStore;
- ReportPage page = ReadObject(null, xmlItem, false, reader) as ReportPage;
- return page.Name;
- }
- }
- internal void ReCalcSizes()
- {
- XmlItem item = xmlItem;
- using (FRReader reader = new FRReader(null, item))
- {
- reader.DeserializeFrom = SerializeTo.Preview;
- reader.BlobStore = preparedPages.BlobStore;
- reader.ReadChildren = false;
- using (ReportPage page = ReadPage(Report, item, false, reader))
- {
- if (page.UnlimitedHeight | page.UnlimitedWidth)
- {
- float maxWidth = 0.0f;
- float maxHeight = 0.0f;
- for (int i = 0; i < item.Count; i++)
- {
- using (Base obj = ReadObject(page, item[i], true, reader))
- {
- if (obj is BandBase)
- {
- BandBase band = obj as BandBase;
- float bandsHeight = band.Top + band.Height;
- if (maxHeight < bandsHeight)
- maxHeight = bandsHeight;
- float bandWidth = 0.0f;
- foreach (ComponentBase comp in band.Objects)
- {
- if ((comp.Anchor & AnchorStyles.Right) == 0 && comp.Dock == DockStyle.None)
- {
- bandWidth = Math.Max(bandWidth, comp.Left + comp.Width);
- }
- }
- if (maxWidth < bandWidth)
- maxWidth = bandWidth;
- }
- }
- }
- if (page.UnlimitedHeight)
- page.UnlimitedHeightValue = maxHeight + (page.TopMargin + page.BottomMargin) * Units.Millimeters;
- if (page.UnlimitedWidth)
- page.UnlimitedWidthValue = maxWidth + (page.LeftMargin + page.RightMargin) * Units.Millimeters;
- }
- pageSize = new SizeF(page.WidthInPixels, page.HeightInPixels);
- using (FRWriter writer = new FRWriter(item))
- {
- writer.SerializeTo = SerializeTo.Preview;
- writer.SaveChildren = false;
- writer.BlobStore = preparedPages.BlobStore;
- writer.Write(page);
- }
- }
- }
- }
- #endregion Internal Methods
- #region Public Methods
- public PreparedPage(ReportPage page, PreparedPages preparedPages)
- {
- this.preparedPages = preparedPages;
- xmlItem = new XmlItem();
- // page == null when we load prepared report from a file
- if (page != null)
- {
- using (FRWriter writer = new FRWriter(xmlItem))
- {
- writer.SerializeTo = SerializeTo.Preview;
- writer.SaveChildren = false;
- writer.Write(page);
- }
- pageSize = new SizeF(page.WidthInPixels, page.HeightInPixels);
- }
- }
- public bool AddBand(BandBase band)
- {
- return DoAdd(band, xmlItem);
- }
- public ReportPage GetPage()
- {
- Load();
- ReportPage page;
- using (FRReader reader = new FRReader(null))
- {
- reader.DeserializeFrom = SerializeTo.Preview;
- reader.ReadChildren = false;
- reader.BlobStore = preparedPages.BlobStore;
- page = ReadPage(null, xmlItem, true, reader);
- }
- page.SetReport(preparedPages.Report);
- new PreparedPagePostprocessor().Postprocess(page);
- ClearUploadedXml();
- return page;
- }
- public void Load()
- {
- if (UseFileCache && uploaded)
- {
- preparedPages.TempFile.Position = tempFilePosition;
- XmlReader reader = new XmlReader(preparedPages.TempFile);
- reader.Read(xmlItem);
- }
- }
- public void ClearUploadedXml()
- {
- if (UseFileCache && uploaded)
- xmlItem.Clear();
- }
- public void Upload()
- {
- if (UseFileCache && !uploaded)
- {
- preparedPages.TempFile.Seek(0, SeekOrigin.End);
- tempFilePosition = preparedPages.TempFile.Position;
- XmlWriter writer = new XmlWriter(preparedPages.TempFile);
- writer.Write(xmlItem);
- xmlItem.Clear();
- uploaded = true;
- }
- }
- public XmlItem CutObjects(int index)
- {
- XmlItem result = new XmlItem();
- while (xmlItem.Count > index)
- {
- result.AddItem(xmlItem[index]);
- }
- return result;
- }
- public void PasteObjects(XmlItem objects, float deltaX, float deltaY)
- {
- if (objects.Count > 0)
- {
- while (objects.Count > 0)
- {
- XmlItem obj = objects[0];
- // shift the object's location
- float objX = (obj.GetProp("l") != "") ?
- Converter.StringToFloat(obj.GetProp("l")) : 0;
- float objY = (obj.GetProp("t") != "") ?
- Converter.StringToFloat(obj.GetProp("t")) : 0;
- obj.SetProp("l", Converter.ToString(objX + deltaX));
- obj.SetProp("t", Converter.ToString(objY + deltaY));
- // add object to a page
- xmlItem.AddItem(obj);
- }
- }
- }
- public float GetLastY()
- {
- float result = 0;
- for (int i = 0; i < xmlItem.Count; i++)
- {
- XmlItem xi = xmlItem[i];
- BandBase obj = preparedPages.Dictionary.GetOriginalObject(xi.Name) as BandBase;
- if (obj != null && !(obj is PageFooterBand) && !(obj is OverlayBand))
- {
- string s = xi.GetProp("t");
- float top = (s != "") ? Converter.StringToFloat(s) : obj.Top;
- s = xi.GetProp("h");
- float height = (s != "") ? Converter.StringToFloat(s) : obj.Height;
- if (top + height > result)
- result = top + height;
- }
- }
- return result;
- }
- public bool ContainsBand(Type bandType)
- {
- for (int i = 0; i < xmlItem.Count; i++)
- {
- XmlItem xi = xmlItem[i];
- BandBase obj = preparedPages.Dictionary.GetOriginalObject(xi.Name) as BandBase;
- if (obj != null && obj.GetType() == bandType)
- return true;
- }
- return false;
- }
- public bool ContainsBand(string bandName)
- {
- for (int i = 0; i < xmlItem.Count; i++)
- {
- XmlItem xi = xmlItem[i];
- BandBase obj = preparedPages.Dictionary.GetOriginalObject(xi.Name) as BandBase;
- if (obj != null && obj.Name == bandName)
- return true;
- }
- return false;
- }
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- xmlItem.Dispose();
- base.Dispose(disposing);
- }
- #endregion Public Methods
- }
- }
|