using FastReport.Utils; using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Drawing.Design; using System.Windows.Forms; namespace FastReport { /// /// Class that implements some object's properties such as location, size and visibility. /// public abstract partial class ComponentBase : Base { #region Fields private AnchorStyles anchor; private DockStyle dock; private int groupIndex; private float height; private float left; private string tag; private float top; private bool visible; private string visibleExpression; private bool printable; private string printableExpression; private float width; #endregion Fields #region Properties /// /// Gets the absolute bottom coordinate of the object. /// [Browsable(false)] public float AbsBottom { get { return AbsTop + Height; } } /// /// Gets the absolute bounding rectangle of the object. /// [Browsable(false)] public RectangleF AbsBounds { get { return new RectangleF(AbsLeft, AbsTop, Width, Height); } } /// /// Gets the absolute left coordinate of the object. /// [Browsable(false)] public virtual float AbsLeft { get { return (Parent is ComponentBase) ? Left + (Parent as ComponentBase).AbsLeft : Left; } } /// /// Gets the absolute right coordinate of the object. /// [Browsable(false)] public float AbsRight { get { return AbsLeft + Width; } } /// /// Gets the absolute top coordinate of the object. /// [Browsable(false)] public virtual float AbsTop { get { return (Parent is ComponentBase) ? Top + (Parent as ComponentBase).AbsTop : Top; } } /// /// Gets or sets the edges of the container to which a control is bound and determines how a control /// is resized with its parent. /// /// /// Use the Anchor property to define how a control is automatically resized as its parent control /// is resized. Anchoring a control to its parent control ensures that the anchored edges remain in the /// same position relative to the edges of the parent control when the parent control is resized. /// You can anchor a control to one or more edges of its container. For example, if you have a band /// with a TextObject whose Anchor property value is set to Top, Bottom, the TextObject is stretched to /// maintain the anchored distance to the top and bottom edges of the band as the height of the band /// is increased. /// [DefaultValue(AnchorStyles.Left | AnchorStyles.Top)] [Category("Layout")] public virtual AnchorStyles Anchor { get { return anchor; } set { anchor = value; } } /// /// Gets the bottom coordinate of the object in relation to its container. /// /// /// To change the bottom coordinate, change the and/or properties. /// [Browsable(false)] public float Bottom { get { return Top + Height; } } /// /// Gets or sets the bounding rectangle of the object. /// /// /// Assigning a value to this property is equal to assigning values to the , /// , , properties. /// [Browsable(false)] public RectangleF Bounds { get { return new RectangleF(Left, Top, Width, Height); } set { Left = value.Left; Top = value.Top; Width = value.Width; Height = value.Height; } } /// /// Gets or sets the size of client area of the object. /// /// /// This property is used in the class. /// [Browsable(false)] public virtual SizeF ClientSize { get { return new SizeF(Width, Height); } set { Width = value.Width; Height = value.Height; } } /// /// Gets or sets which control borders are docked to its parent control and determines how a control /// is resized with its parent. /// /// /// Use the Dock property to define how a control is automatically resized as its parent control is /// resized. For example, setting Dock to DockStyle.Left causes the control to align itself with the /// left edges of its parent control and to resize as the parent control is resized. /// A control can be docked to one edge of its parent container or can be docked to all edges and /// fill the parent container. /// [DefaultValue(DockStyle.None)] [Category("Layout")] public virtual DockStyle Dock { get { return dock; } set { if (dock != value) { dock = value; if (Parent != null) (Parent as IParent).UpdateLayout(0, 0); } } } /// /// Gets or sets a group index. /// /// /// Group index is used to group objects in the designer (using "Group" button). When you select /// any object in a group, entire group becomes selected. To reset a group, set the GroupIndex /// to 0 (default value). /// [Browsable(false)] public int GroupIndex { get { return groupIndex; } set { groupIndex = value; } } /// /// Gets or sets the height of the object. /// /// /// This property value is measured in the screen pixels. Use class to /// convert a value to desired units. /// /// The following example demonstrates how to convert between pixels and units: /// TextObject text1; /// // set Height to 10mm /// text1.Height = Units.Millimeters * 10; /// // convert a value to millimeters /// MessageBox.Show("Height = " + (text1.Height / Units.Millimeters).ToString() + "mm"); /// [Category("Layout")] public virtual float Height { get { return height; } set { value = (float)Math.Round(value, 2); if (FloatDiff(height, value)) { if (!IsDesigning || !HasRestriction(Restrictions.DontResize)) { if (this is IParent) (this as IParent).UpdateLayout(0, value - height); height = value; if (Dock != DockStyle.None && Parent != null) (Parent as IParent).UpdateLayout(0, 0); } } } } /// /// Gets or sets the left coordinate of the object in relation to its container. /// /// /// /// This property value is measured in the screen pixels. Use /// class to convert a value to desired units. /// /// /// To obtain absolute coordinate, use property. /// /// /// The following example demonstrates how to convert between pixels and units: /// TextObject text1; /// // set Left to 10mm /// text1.Left = Units.Millimeters * 10; /// // convert a value to millimeters /// MessageBox.Show("Left = " + (text1.Left / Units.Millimeters).ToString() + "mm"); /// [Category("Layout")] public virtual float Left { get { return left; } set { value = (float)Math.Round(value, 2); if (!IsDesigning || !HasRestriction(Restrictions.DontMove)) { left = value; if (Dock != DockStyle.None && Parent != null) (Parent as IParent).UpdateLayout(0, 0); } } } /// /// Gets the right coordinate of the object in relation to its container. /// /// /// To change the right coordinate, change the and/or properties. /// [Browsable(false)] public float Right { get { return Left + Width; } } /// /// Gets or sets the Tag string for this component. /// [Category("Design")] public string Tag { get { return tag; } set { tag = value; } } /// /// Gets or sets the top coordinate of the object in relation to its container. /// /// /// /// This property value is measured in the screen pixels. Use /// class to convert a value to desired units. /// /// /// To obtain absolute coordinate, use property. /// /// /// The following example demonstrates how to convert between pixels and units: /// TextObject text1; /// // set Top to 10mm /// text1.Top = Units.Millimeters * 10; /// // convert a value to millimeters /// MessageBox.Show("Top = " + (text1.Top / Units.Millimeters).ToString() + "mm"); /// [Category("Layout")] public virtual float Top { get { return top; } set { value = (float)Math.Round(value, 2); if (!IsDesigning || !HasRestriction(Restrictions.DontMove)) { top = value; if (Dock != DockStyle.None && Parent != null) (Parent as IParent).UpdateLayout(0, 0); } } } /// /// Gets or sets a value indicating whether the object is displayed in the preview window. /// /// /// Setting this property to false will hide the object in the preview window. /// /// The following report script will control the Text1 visibility depending on the value of the /// data column: /// private void Data1_BeforePrint(object sender, EventArgs e) /// { /// Text1.Visible = [Orders.Shipped] == true; /// } /// [DefaultValue(true)] [Category("Behavior")] public virtual bool Visible { get { return visible; } set { visible = value; } } /// /// Gets or sets a string containing expression that determines should be object displayed in the preview window. /// [DefaultValue("")] [Category("Behavior")] [Editor("FastReport.TypeEditors.ExpressionEditor, FastReport", typeof(UITypeEditor))] public virtual string VisibleExpression { get { return visibleExpression; } set { visibleExpression = value; } } /// /// Gets or sets a value that determines if the object can be printed on the printer. /// /// /// Object with Printable = false is still visible in the preview window, but not on the printout. /// If you want to hide an object in the preview, set the property to false. /// [DefaultValue(true)] [Category("Behavior")] public bool Printable { get { return printable; } set { printable = value; } } /// /// Gets or sets a string containing expression that determines should be object printed on the printer. /// [DefaultValue("")] [Category("Behavior")] [Editor("FastReport.TypeEditors.ExpressionEditor, FastReport", typeof(UITypeEditor))] public string PrintableExpression { get { return printableExpression; } set { printableExpression = value; } } /// /// Gets or sets the width of the object. /// /// /// This property value is measured in the screen pixels. Use class to /// convert a value to desired units. /// /// The following example demonstrates how to convert between pixels and units: /// TextObject text1; /// // set Width to 10mm /// text1.Width = Units.Millimeters * 10; /// // convert a value to millimeters /// MessageBox.Show("Width = " + (text1.Width / Units.Millimeters).ToString() + "mm"); /// [Category("Layout")] public virtual float Width { get { return width; } set { value = (float)Math.Round(value, 2); if (FloatDiff(width, value)) { if (!IsDesigning || !HasRestriction(Restrictions.DontResize)) { if (this is IParent) (this as IParent).UpdateLayout(value - width, 0); width = value; if (Dock != DockStyle.None && Parent != null) (Parent as IParent).UpdateLayout(0, 0); } } } } #endregion Properties #region Constructors /// /// Initializes a new instance of the class with default settings. /// public ComponentBase() { anchor = AnchorStyles.Left | AnchorStyles.Top; visible = true; visibleExpression = ""; printable = true; printableExpression = ""; SetFlags(Flags.CanWriteBounds | Flags.HasGlobalName, true); tag = ""; } #endregion Constructors #region Public Methods /// public override void Assign(Base source) { base.Assign(source); ComponentBase src = source as ComponentBase; Left = src.Left; Top = src.Top; Width = src.Width; Height = src.Height; Dock = src.Dock; Anchor = src.Anchor; Visible = src.Visible; VisibleExpression = src.VisibleExpression; Printable = src.Printable; PrintableExpression = src.PrintableExpression; Tag = src.Tag; } /// public override void Serialize(FRWriter writer) { ComponentBase c = writer.DiffObject as ComponentBase; base.Serialize(writer); if (Printable != c.Printable) writer.WriteBool("Printable", Printable); if (PrintableExpression != c.PrintableExpression) writer.WriteStr("PrintableExpression", PrintableExpression); if (HasFlag(Flags.CanWriteBounds)) { if (FloatDiff(Left, c.Left)) writer.WriteFloat("Left", Left); if (FloatDiff(Top, c.Top)) writer.WriteFloat("Top", Top); if (FloatDiff(Width, c.Width)) writer.WriteFloat("Width", Width); if (FloatDiff(Height, c.Height)) writer.WriteFloat("Height", Height); } if (writer.SerializeTo != SerializeTo.Preview) { if (Dock != c.Dock) writer.WriteValue("Dock", Dock); if (Anchor != c.Anchor) writer.WriteValue("Anchor", Anchor); if (Visible != c.Visible) writer.WriteBool("Visible", Visible); if (VisibleExpression != c.VisibleExpression) writer.WriteStr("VisibleExpression", VisibleExpression); if (GroupIndex != c.GroupIndex) writer.WriteInt("GroupIndex", GroupIndex); } if (Tag != c.Tag) writer.WriteStr("Tag", Tag); } #endregion Public Methods #region Report Engine /// public override string[] GetExpressions() { List expressions = new List(); string[] baseExpressions = base.GetExpressions(); if (baseExpressions != null) { expressions.AddRange(baseExpressions); } if (!String.IsNullOrEmpty(VisibleExpression)) { string expression = Code.CodeUtils.FixExpressionWithBrackets(VisibleExpression); if (expression.ToLower() == "true" || expression.ToLower() == "false") { expression = expression.ToLower(); } expressions.Add(expression); } if (!String.IsNullOrEmpty(PrintableExpression)) { string expression = Code.CodeUtils.FixExpressionWithBrackets(PrintableExpression); if (expression.ToLower() == "true" || expression.ToLower() == "false") { expression = expression.ToLower(); } expressions.Add(expression); } return expressions.ToArray(); } /// /// Caclulates visible expression value. /// /// The expression to calculate. /// The result of calculation. public bool CalcVisibleExpression(string expression) { bool result = true; object expressionObj = null; // Calculate expressions with TotalPages only on FinalPass. if (!expression.Contains("TotalPages") || (Report.DoublePass && Report.Engine.FinalPass)) { expressionObj = Report.Calc(Code.CodeUtils.FixExpressionWithBrackets(expression)); } if (expressionObj != null && expressionObj is bool) { if (!expression.Contains("TotalPages")) { result = (bool)expressionObj; } else if (Report.Engine.FirstPass) { result = true; } else { result = (bool)expressionObj; } } return result; } #endregion Report Engine } }