using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.ComponentModel;
using FastReport.Utils;
#if NETSTANDARD || NETCOREAPP
using FastReport.Code.CodeDom.Compiler;
#else
using System.CodeDom.Compiler;
#endif
using System.Drawing.Design;
namespace FastReport
{
///
/// Specifies a set of actions that cannot be performed on the object in the design mode.
///
[Flags]
[TypeConverter(typeof(FastReport.TypeConverters.FlagConverter))]
public enum Restrictions
{
///
/// Specifies no restrictions.
///
None = 0,
///
/// Restricts moving the object.
///
DontMove = 1,
///
/// Restricts resizing the object.
///
DontResize = 2,
///
/// Restricts modifying the object's properties.
///
DontModify = 4,
///
/// Restricts editing the object.
///
DontEdit = 8,
///
/// Restricts deleting the object.
///
DontDelete = 16,
///
/// Hides all properties of the object.
///
HideAllProperties = 32
}
///
/// Specifies a set of actions that can be performed on the object in the design mode.
///
[Flags]
[TypeConverter(typeof(FastReport.TypeConverters.FlagConverter))]
public enum Flags
{
///
/// Specifies no actions.
///
None = 0,
///
/// Allows moving the object.
///
CanMove = 1,
///
/// Allows resizing the object.
///
CanResize = 2,
///
/// Allows deleting the object.
///
CanDelete = 4,
///
/// Allows editing the object.
///
CanEdit = 8,
///
/// Allows changing the Z-order of an object.
///
CanChangeOrder = 16,
///
/// Allows moving the object to another parent.
///
CanChangeParent = 32,
///
/// Allows copying the object to the clipboard.
///
CanCopy = 64,
///
/// Allows drawing the object.
///
CanDraw = 128,
///
/// Allows grouping the object.
///
CanGroup = 256,
///
/// Allows write children in the preview mode by itself.
///
CanWriteChildren = 512,
///
/// Allows write object's bounds into the report stream.
///
CanWriteBounds = 1024,
///
/// Allows the "smart tag" functionality.
///
HasSmartTag = 2048,
///
/// Specifies that the object's name is global (this is true for all report objects
/// such as Text, Picture and so on).
///
HasGlobalName = 4096,
///
/// Specifies that the object can display children in the designer's Report Tree window.
///
CanShowChildrenInReportTree = 8192,
///
/// Specifies that the object supports mouse wheel in the preview window.
///
InterceptsPreviewMouseEvents = 16384
}
[Flags]
internal enum ObjectState : byte
{
None = 0,
IsAncestor = 1,
IsDesigning = 2,
IsPrinting = 4,
IsRunning = 8,
IsDeserializing = 16,
}
///
/// Represents the root class of the FastReport object's hierarchy.
///
[ToolboxItem(false)]
public abstract partial class Base : Component, IFRSerializable
{
#region Fields
private string name;
private Restrictions restrictions;
private Flags flags;
private Base parent;
private string baseName;
private ObjectState objectState;
private Base originalComponent;
private string alias;
private Report report;
private int zOrder;
#endregion
#region Properties
///
/// Gets or sets the name of the object.
///
///
/// Name of the report object must contain alpha, digit, underscore symbols only.
/// Data objects such as Variable, TableDataSource
/// etc. can have any characters in they names. Each component must have unique
/// name.
///
/// The following code demonstrates how to find an object by its name:
///
/// TextObject text1 = report1.FindObject("Text1") as TextObject;
///
///
/// Another object with such name exists.
/// Rename an object that was introduced in the ancestor report.
[MergableProperty(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Category("Design")]
[DisplayName("(Name)")]
public virtual string Name
{
get { return name; }
set
{
if (String.Compare(name, value, true) == 0)
return;
if (value != "" && Report != null && HasFlag(Flags.HasGlobalName))
{
Base c = Report.FindObject(value);
if (c != null && c != this)
throw new DuplicateNameException(value);
if (IsAncestor)
throw new AncestorException(name);
if (IsDesigning)
CheckValidIdent(value);
}
SetName(value);
}
}
///
/// Gets or sets the flags that restrict some actions in the designer.
///
///
/// Use this property to restrict some user actions like move, resize, edit, delete. For example, if
/// Restriction.DontMove flag is set, user cannot move the object in the designer.
///
[DefaultValue(Restrictions.None)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Category("Design")]
[Editor("FastReport.TypeEditors.FlagsEditor, FastReport", typeof(UITypeEditor))]
public Restrictions Restrictions
{
get { return restrictions; }
set { restrictions = value; }
}
///
/// Gets the flags that allow some functionality in the designer.
///
///
/// Use this property only if you developing a new FastReport object.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Flags Flags
{
get { return flags; }
}
///
/// Gets or sets the parent of the object.
///
///
/// Each report object must have a parent in order to appear in the report. Parent must be able to
/// contain objects of such type.
/// Another way (preferred) to set a parent is to use specific properties of the parent object.
/// For example, the object has the collection.
/// To add a new page to the report, use the following code: report1.Pages.Add(new ReportPage());
///
///
///
/// Report report1;
/// ReportPage page = new ReportPage();
/// page.Parent = report1;
///
/// Parent object cannot contain this object.
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Base Parent
{
get { return parent; }
set
{
if (value != parent)
{
if (value != null)
{
if (value is IParent)
(value as IParent).AddChild(this);
}
else
{
(parent as IParent).RemoveChild(this);
}
}
}
}
///
/// The base part of the object's name.
///
///
/// This property is used to automatically create unique object's name. See
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string BaseName
{
get { return baseName; }
set { baseName = value; }
}
///
/// Gets the short type name.
///
///
/// Returns the short type name, such as "TextObject".
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string ClassName
{
get { return GetType().Name; }
}
///
/// Gets reference to the parent object.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Report Report
{
get
{
if (this is Report)
return this as Report;
if (report != null)
return report;
if (Parent != null)
return Parent.Report;
return null;
}
}
///
/// Gets reference to the parent object.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public PageBase Page
{
get
{
if (this is PageBase)
return (PageBase)this;
Base c = Parent;
while (c != null)
{
if (c is PageBase)
return (PageBase)c;
c = c.Parent;
}
return null;
}
}
///
/// Gets the collection of this object's child objects.
///
///
/// This property returns child objects that belongs to this object. For example, Report.ChildObjects
/// will return only pages that contains in the report, but not page childs such as bands. To return all
/// child objects, use property.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public ObjectCollection ChildObjects
{
get
{
ObjectCollection result = new ObjectCollection();
if (this is IParent)
(this as IParent).GetChildObjects(result);
return result;
}
}
///
/// Gets the collection of all child objects.
///
///
/// This property returns child objects that belongs to this object and to child objects of this object.
/// For example, Report.AllObjects will return all objects that contains in the report - such as
/// pages, bands, text objects.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public ObjectCollection AllObjects
{
get
{
ObjectCollection result = new ObjectCollection();
EnumObjects(this, result);
return result;
}
}
///
/// Gets or sets the Z-order of the object.
///
///
/// The Z-order is also called "creation order". It is the index of an object in the parent's objects list.
/// For example, put two text objects on a band. First object will have ZOrder = 0, second = 1. Setting the
/// second object's ZOrder to 0 will move it to the back of the first text object.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int ZOrder
{
get
{
if (parent != null)
return (parent as IParent).GetChildOrder(this);
return zOrder;
}
set
{
if (parent != null)
(parent as IParent).SetChildOrder(this, value);
else
zOrder = value;
}
}
///
/// Gets a value indicating whether the object was introduced in the ancestor report.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsAncestor
{
get { return GetObjectState(ObjectState.IsAncestor); }
}
///
/// Gets a value indicating whether the object is in the design state.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsDesigning
{
get { return GetObjectState(ObjectState.IsDesigning); }
}
///
/// Gets a value indicating whether the object is currently printing.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsPrinting
{
get { return GetObjectState(ObjectState.IsPrinting); }
}
///
/// Gets a value indicating whether the object is currently processed by the report engine.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsRunning
{
get { return GetObjectState(ObjectState.IsRunning); }
}
///
/// Gets a value indicating whether the object is currently processed by the report engine.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
internal bool IsDeserializing
{
get { return GetObjectState(ObjectState.IsDeserializing); }
set { SetObjectState(ObjectState.IsDeserializing, value); }
}
///
/// Gets an original component for this object.
///
///
/// This property is used in the preview mode. Each object in the prepared report is bound to its
/// original (from the report template). This technique is used to minimize the prepared report's size.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Base OriginalComponent
{
get { return originalComponent; }
set { originalComponent = value; }
}
internal string Alias
{
get { return alias; }
set { alias = value; }
}
#endregion
#region Private Methods
private void CheckValidIdent(string value)
{
if (!CodeGenerator.IsValidLanguageIndependentIdentifier(value))
throw new NotValidIdentifierException(value);
}
private void EnumObjects(Base c, ObjectCollection list)
{
if (c != this)
list.Add(c);
foreach (Base obj in c.ChildObjects)
EnumObjects(obj, list);
}
#endregion
#region Protected Methods
///
/// Helper method, helps to set a reference-type value to the property.
///
/// Old property value.
/// New property value.
///
/// This method is used widely to set a new value to the property that references another FastReport object.
/// Method deals with the property.
///
/// This is example of the DataBand.Header property:
/// public DataHeaderBand Header
/// {
/// get { return FHeader; }
/// set
/// {
/// SetProp(FHeader, value);
/// FHeader = value;
/// }
/// }
///
protected void SetProp(Base prop, Base value)
{
if (prop != value)
{
if (prop != null)
prop.SetParent(null);
if (value != null)
{
value.Parent = null;
value.SetParent(this);
}
}
}
///
/// Checks if two float values are different.
///
/// First value.
/// Second value.
/// true if values are not equal.
///
/// This method is needed to compare two float values using some precision (0.001). It is useful
/// to compare objects' locations and sizes for equality.
///
protected bool FloatDiff(float f1, float f2)
{
return Math.Abs(f1 - f2) > 0.001;
}
///
/// Deserializes nested object properties.
///
/// Reader object.
///
/// Typically the object serializes all properties to the single xml item:
///
/// <TextObject Name="Text2" Left="18.9" Top="37.8" Width="283.5" Height="28.35"/>
///
/// Some objects like have child objects that serialized in subitems:
///
/// <DataBand Name="Data1" Top="163" Width="718.2" Height="18.9">
/// <TextObject Name="Text3" Left="18.9" Top="37.8" Width="283.5" Height="28.35"/>
/// </DataBand>
///
/// To read such subitems, the DeserializeSubItems method is used. Base
/// implementation reads the child objects. You may override it to read some specific subitems.
///
/// The following code is used to read report's styles:
///
/// protected override void DeserializeSubItems(FRReader reader)
/// {
/// if (String.Compare(reader.ItemName, "Styles", true) == 0)
/// reader.Read(Styles);
/// else
/// base.DeserializeSubItems(reader);
/// }
///
///
protected virtual void DeserializeSubItems(FRReader reader)
{
if (reader.ReadChildren)
{
Base obj = reader.Read() as Base;
if (obj != null)
{
obj.Parent = this;
if (IsAncestor && !obj.IsAncestor)
obj.ZOrder = obj.zOrder;
}
}
}
///
/// Replaces the macros in the given string and returns the new string.
///
/// The text containing macros.
/// The text with macros replaced with its values.
protected string ExtractDefaultMacros(string text)
{
Dictionary macroValues = Report.PreparedPages.MacroValues;
text = ExtractDefaultMacrosInternal(macroValues, text);
text = text.Replace("[TOTALPAGES#]", macroValues["TotalPages#"].ToString());
text = text.Replace("[PAGE#]", macroValues["Page#"].ToString());
return text;
}
///
protected override void Dispose(bool disposing)
{
if (disposing)
{
Clear();
Parent = null;
}
base.Dispose(disposing);
}
#endregion
#region Public Methods
///
/// Set object's flags.
///
/// Flag to set.
/// true to set the flag, false to reset.
public void SetFlags(Flags flags, bool value)
{
if (value)
this.flags |= flags;
else
this.flags &= ~flags;
}
private bool GetObjectState(ObjectState state)
{
return (objectState & state) > 0;
}
private void SetObjectState(ObjectState state, bool value)
{
if (value)
this.objectState |= state;
else
this.objectState &= ~state;
}
internal void SetAncestor(bool value)
{
SetObjectState(ObjectState.IsAncestor, value);
}
internal void SetDesigning(bool value)
{
SetObjectState(ObjectState.IsDesigning, value);
}
internal void SetPrinting(bool value)
{
SetObjectState(ObjectState.IsPrinting, value);
}
internal void SetRunning(bool value)
{
SetObjectState(ObjectState.IsRunning, value);
}
///
/// Sets the reference to a Report.
///
/// Report to set.
public void SetReport(Report value)
{
report = value;
}
///
/// Sets the object's name.
///
///
/// This method is for internal use only. It just sets a new name without any checks
/// (unlike the property setter).
///
/// Name Property
/// New name.
public virtual void SetName(string value)
{
name = value;
}
///
/// Sets the object's parent.
///
///
/// This method is for internal use only. You can use it if you are developing a new
/// component for FastReport. Override it to perform some actions when the parent of an
/// object is changing. This method checks that parent can contain a child.
///
/// Parent object cannot contain this object.
/// New parent.
public virtual void SetParent(Base value)
{
if (value != null)
if (!(value is IParent) || !(value as IParent).CanContain(this))
throw new ParentException(value, this);
SetParentCore(value);
}
///
/// Sets the object's parent.
///
/// New parent.
///
/// This method is for internal use only. You can use it if you are developing a new component for FastReport.
/// This method does not perform any checks, it just sets the new parent.
///
public void SetParentCore(Base value)
{
parent = value;
}
///
/// Searches for an object with given name.
///
/// Name of the object to find.
/// Returns a null reference if object is not found
/// The following code demonstrates how to find an object by its name:
///
/// TextObject text1 = report1.FindObject("Text1") as TextObject;
/// if (text1 != null)
/// {
/// // object found
/// }
///
///
public virtual Base FindObject(string name)
{
ObjectCollection l = AllObjects;
foreach (Base c in l)
{
if (name == c.Name)
return c;
}
return null;
}
///
/// Creates the unique object's name.
///
///
/// Note: you have to set object's parent before calling this method. Method uses the
/// property to create a name.
/// Note: this method may be very slow on a report that contains lots of objects. Consider
/// using own naming logic in this case.
///
///
///
/// TextObject textObj = new TextObject();
/// dataBand1.Objects.Add(textObj);
/// textObj.CreateUniqueName();
///
///
public void CreateUniqueName()
{
Report report = Report;
if (report == null)
return;
string s;
int i = 1;
do
{
s = baseName + i.ToString();
i++;
}
while (report.FindObject(s) != null);
SetName(s);
}
///
/// Clears the object's state.
///
///
/// This method also disposes all object's children.
///
public virtual void Clear()
{
ObjectCollection list = ChildObjects;
foreach (Base c in list)
{
c.Clear();
c.Dispose();
}
}
///
/// Serializes the object.
///
///
/// Do not call this method directly. You should override it if you are
/// developing a new component for FastReport.
/// This method is called when the object needs to save the state. It may happen
/// when:
///
/// -
/// saving the report to the file or stream;
///
/// -
/// saving the report to the designer's undo buffer;
///
/// -
///
/// assigning the object to another object using the
/// or AssignAll methods;
///
///
/// -
/// saving the object to the designer's clipboard;
///
/// -
/// saving the object to the preview (when run a
/// report).
///
///
///
/// Writer object.
public virtual void Serialize(FRWriter writer)
{
Base c = writer.DiffObject as Base;
if (writer.SerializeTo != SerializeTo.Preview)
{
// in the preview mode we don't need to write ItemName and Name properties. Alias is written instead.
writer.ItemName = IsAncestor &&
(writer.SerializeTo == SerializeTo.Report || writer.SerializeTo == SerializeTo.Undo) ?
"inherited" : ClassName;
if (Name != "")
writer.WriteStr("Name", Name);
if (Restrictions != c.Restrictions)
writer.WriteValue("Restrictions", Restrictions);
if ((writer.SerializeTo == SerializeTo.Report || writer.SerializeTo == SerializeTo.Undo) &&
!IsAncestor && Parent != null && Parent.IsAncestor)
writer.WriteInt("ZOrder", ZOrder);
}
if (writer.SaveChildren)
{
foreach (Base child in ChildObjects)
{
writer.Write(child);
}
}
}
///
/// Deserializes the object.
///
///
/// Do not call this method directly. You should override it if you are
/// developing a new component for FastReport.
/// This method is called when the object needs to restore the state. It may
/// happen when:
///
/// -
/// loading the report from a file or stream;
///
/// -
/// loading the report from the designer's undo
/// buffer;
///
/// -
/// assigning another object to this object using the
/// or AssignAll methods;
///
/// -
/// loading the object from the designer's
/// clipboard;
///
/// - loading the object from the preview pages.
///
///
/// Reader object.
public virtual void Deserialize(FRReader reader)
{
try
{
IsDeserializing = true;
reader.ReadProperties(this);
while (reader.NextItem())
{
DeserializeSubItems(reader);
}
}
finally
{
IsDeserializing = false;
}
}
///
/// Assigns values from another source.
///
///
/// Note: this method is relatively slow because it serializes
/// an object to the xml and then deserializes it.
///
/// Source to assign from.
public void BaseAssign(Base source)
{
bool saveAncestor = source.IsAncestor;
source.SetAncestor(false);
try
{
using (XmlItem xml = new XmlItem())
using (FRWriter writer = new FRWriter(xml))
using (FRReader reader = new FRReader(Report, xml))
{
writer.SaveChildren = false;
writer.Write(source, this);
reader.Read(this);
}
Alias = source.Alias;
OriginalComponent = source.OriginalComponent;
}
finally
{
source.SetAncestor(saveAncestor);
}
}
/// Copies the contents of another, similar object.
///
/// Call Assign to copy the properties from another object of the same type.
/// The standard form of a call to Assign is
/// destination.Assign(source);
///
/// which tells the destination object to copy the contents of the
/// source object to itself. In this method, all child objects are
/// ignored. If you want to copy child objects, use the
/// AssignAll method.
///
///
///
/// Report report1;
/// Report report2 = new Report();
/// // copy all report settings, do not copy report objects
/// report2.Assign(report1);
///
/// AssignAll Method
/// Source object to copy the contents from.
public virtual void Assign(Base source)
{
Restrictions = source.Restrictions;
Alias = source.Alias;
OriginalComponent = source.OriginalComponent;
}
/// Copies the contents (including children) of another, similar object.
///
///
/// This method is similar to method. It copies child
/// objects as well.
///
///
///
/// Report report1;
/// Report report2 = new Report();
/// // copy all report settings and objects
/// report2.AssignAll(report1);
///
///
/// Source object to copy the state from.
public void AssignAll(Base source)
{
AssignAll(source, false);
}
internal void AssignAll(Base source, bool assignName)
{
Clear();
Assign(source);
if (assignName)
SetName(source.Name);
foreach (Base child in source.ChildObjects)
{
Base myChild = Activator.CreateInstance(child.GetType()) as Base;
myChild.SetReport(Report);
myChild.AssignAll(child, assignName);
myChild.SetReport(null);
myChild.Parent = this;
}
}
///
/// Gets a value indicating whether the object has the specified parent in its parent hierarchy.
///
/// Parent object to check.
/// Returns true if the object has given parent in its parent hierarchy.
public bool HasParent(Base obj)
{
Base parent = Parent;
while (parent != null)
{
if (parent == obj)
return true;
parent = parent.Parent;
}
return false;
}
///
/// Gets a value indicating whether the object has a specified flag in its property.
///
/// Flag to check.
/// true if Flags property contains specified flag.
public bool HasFlag(Flags flag)
{
return (Flags & flag) > 0;
}
///
/// Gets a value indicating whether the object has a specified restriction
/// in its property.
///
/// Restriction to check.
/// true if Restrictions property contains specified restriction.
public bool HasRestriction(Restrictions restriction)
{
return (Restrictions & restriction) > 0;
}
///
/// Invokes script event.
///
/// Name of the event to invoke.
/// Event parameters.
///
/// Do not call this method directly. You should use it if you are developing a new component
/// for FastReport.
/// Use this method to call an event handler that is located in the report's script.
///
/// Example of the OnBeforePrint method:
/// public void OnBeforePrint(EventArgs e)
/// {
/// if (BeforePrint != null)
/// BeforePrint(this, e);
/// InvokeEvent(BeforePrintEvent, e);
/// }
///
public void InvokeEvent(string name, object param)
{
if (String.IsNullOrEmpty(name))
return;
Report report = Report;
if (report != null)
report.InvokeMethod(name, new object[] { this, param });
}
///
/// Called after all report objects were loaded.
///
///
/// Do not call this method directly. You may override it if you are developing a new component
/// for FastReport.
///
public virtual void OnAfterLoad()
{
}
///
/// Gets all expressions contained in the object.
///
/// Array of expressions or null if object contains no expressions.
///
/// Do not call this method directly. You may override it if you are developing a
/// new component for FastReport.
///
/// This method is called by FastReport each time before run a report. FastReport
/// do this to collect all expressions and compile them. For example,
/// GetExpressions method of the class
/// parses the text and returns all expressions found in the text.
///
///
public virtual string[] GetExpressions()
{
return null;
}
///
/// Returns a custom code that will be added to the report script before report is run.
///
/// A custom script text, if any. Otherwise returns null.
///
/// This method may return any valid code that may be inserted into the report script. Currently it is
/// used in the TableObject to define the following script methods: Sum, Min, Max, Avg, Count.
///
///
/// Note: you must take into account the current script language - C# or VB.Net. You may check it via
/// Report.ScriptLanguage property.
///
///
public virtual string GetCustomScript()
{
return null;
}
///
/// Used to extract macros such as "TotalPages#" in the preview mode.
///
///
/// This method is used mainly by the TextObject to extract macros and replace it with
/// actual values passed in the pageIndex and totalPages parameters. This method
/// is called automatically when the object is being previewed.
///
public virtual void ExtractMacros()
{
}
///
/// Used to get information of the need to convertation if the function returns true, then the GetConvertedObjects function is called
///
/// The export or the object, that call this method
/// By default returns false
///
/// The functions IsHaveToConvert and GetConvertedObjects allow you to convert objects from one to another,
/// for example the export will convert object before adding it to the file and convert recursive,
/// i.e. If the new object has the ability to convert,
/// it will be converted again but limit is 10 times.
/// At the time of export it is called, only on objects inside the band,
/// the child objects of converted object will be returned, and the child objects of old object will be ignored.
///
public virtual bool IsHaveToConvert(object sender)
{
return false;
}
///
/// Used to get an enumeration of the objects to which this object will be converted, before calling this function, the IsHaveToConvert function will be called
///
/// By default returns this object
///
/// The functions IsHaveToConvert and GetConvertedObjects allow you to convert objects from one to another,
/// for example the export will convert object before adding it to the file and convert recursive,
/// i.e. If the new object has the ability to convert,
/// it will be converted again but limit is 10 times.
/// At the time of export it is called, only on objects inside the band,
/// the child objects of converted object will be returned, and the child objects of old object will be ignored.
///
public virtual IEnumerable GetConvertedObjects()
{
yield return this;
}
///
/// Gets the collection of all child objects, converts objects if necessary
///
/// the object or export, that call this convertation
public ObjectCollection ForEachAllConvectedObjects(object sender)
{
ObjectCollection list = new ObjectCollection();
EnumAllConvertedObjects(sender, this, list, 0);
return list;
}
private void EnumAllConvertedObjects(object sender, Base c, ObjectCollection list, int convertValue)
{
if (c != this)
{
if (c.IsHaveToConvert(sender))
{
if (convertValue < 10)
{
foreach (Base b in c.GetConvertedObjects())
EnumAllConvertedObjects(sender, b, list, convertValue + 1);
return;
}
}
list.Add(c);
}
foreach (Base obj in c.ChildObjects)
EnumAllConvertedObjects(sender, obj, list, convertValue);
}
#endregion
///
/// Initializes a new instance of the Base class with default settings.
///
public Base()
{
name = "";
alias = "";
baseName = ClassName;
restrictions = new Restrictions();
SetFlags(Flags.CanMove | Flags.CanResize | Flags.CanDelete | Flags.CanEdit | Flags.CanChangeOrder |
Flags.CanChangeParent | Flags.CanCopy | Flags.CanDraw | Flags.CanShowChildrenInReportTree, true);
}
}
}