Base.cs 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204
  1. using System;
  2. using System.IO;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Drawing;
  6. using System.ComponentModel;
  7. using FastReport.Utils;
  8. #if NETSTANDARD || NETCOREAPP
  9. using FastReport.Code.CodeDom.Compiler;
  10. #else
  11. using System.CodeDom.Compiler;
  12. #endif
  13. using System.Drawing.Design;
  14. namespace FastReport
  15. {
  16. /// <summary>
  17. /// Specifies a set of actions that cannot be performed on the object in the design mode.
  18. /// </summary>
  19. [Flags]
  20. [TypeConverter(typeof(FastReport.TypeConverters.FlagConverter))]
  21. public enum Restrictions
  22. {
  23. /// <summary>
  24. /// Specifies no restrictions.
  25. /// </summary>
  26. None = 0,
  27. /// <summary>
  28. /// Restricts moving the object.
  29. /// </summary>
  30. DontMove = 1,
  31. /// <summary>
  32. /// Restricts resizing the object.
  33. /// </summary>
  34. DontResize = 2,
  35. /// <summary>
  36. /// Restricts modifying the object's properties.
  37. /// </summary>
  38. DontModify = 4,
  39. /// <summary>
  40. /// Restricts editing the object.
  41. /// </summary>
  42. DontEdit = 8,
  43. /// <summary>
  44. /// Restricts deleting the object.
  45. /// </summary>
  46. DontDelete = 16,
  47. /// <summary>
  48. /// Hides all properties of the object.
  49. /// </summary>
  50. HideAllProperties = 32
  51. }
  52. /// <summary>
  53. /// Specifies a set of actions that can be performed on the object in the design mode.
  54. /// </summary>
  55. [Flags]
  56. [TypeConverter(typeof(FastReport.TypeConverters.FlagConverter))]
  57. public enum Flags
  58. {
  59. /// <summary>
  60. /// Specifies no actions.
  61. /// </summary>
  62. None = 0,
  63. /// <summary>
  64. /// Allows moving the object.
  65. /// </summary>
  66. CanMove = 1,
  67. /// <summary>
  68. /// Allows resizing the object.
  69. /// </summary>
  70. CanResize = 2,
  71. /// <summary>
  72. /// Allows deleting the object.
  73. /// </summary>
  74. CanDelete = 4,
  75. /// <summary>
  76. /// Allows editing the object.
  77. /// </summary>
  78. CanEdit = 8,
  79. /// <summary>
  80. /// Allows changing the Z-order of an object.
  81. /// </summary>
  82. CanChangeOrder = 16,
  83. /// <summary>
  84. /// Allows moving the object to another parent.
  85. /// </summary>
  86. CanChangeParent = 32,
  87. /// <summary>
  88. /// Allows copying the object to the clipboard.
  89. /// </summary>
  90. CanCopy = 64,
  91. /// <summary>
  92. /// Allows drawing the object.
  93. /// </summary>
  94. CanDraw = 128,
  95. /// <summary>
  96. /// Allows grouping the object.
  97. /// </summary>
  98. CanGroup = 256,
  99. /// <summary>
  100. /// Allows write children in the preview mode by itself.
  101. /// </summary>
  102. CanWriteChildren = 512,
  103. /// <summary>
  104. /// Allows write object's bounds into the report stream.
  105. /// </summary>
  106. CanWriteBounds = 1024,
  107. /// <summary>
  108. /// Allows the "smart tag" functionality.
  109. /// </summary>
  110. HasSmartTag = 2048,
  111. /// <summary>
  112. /// Specifies that the object's name is global (this is true for all report objects
  113. /// such as Text, Picture and so on).
  114. /// </summary>
  115. HasGlobalName = 4096,
  116. /// <summary>
  117. /// Specifies that the object can display children in the designer's Report Tree window.
  118. /// </summary>
  119. CanShowChildrenInReportTree = 8192,
  120. /// <summary>
  121. /// Specifies that the object supports mouse wheel in the preview window.
  122. /// </summary>
  123. InterceptsPreviewMouseEvents = 16384
  124. }
  125. [Flags]
  126. internal enum ObjectState : byte
  127. {
  128. None = 0,
  129. IsAncestor = 1,
  130. IsDesigning = 2,
  131. IsPrinting = 4,
  132. IsRunning = 8,
  133. IsDeserializing = 16,
  134. }
  135. /// <summary>
  136. /// Represents the root class of the FastReport object's hierarchy.
  137. /// </summary>
  138. [ToolboxItem(false)]
  139. public abstract partial class Base : Component, IFRSerializable
  140. {
  141. #region Fields
  142. private string name;
  143. private Restrictions restrictions;
  144. private Flags flags;
  145. private Base parent;
  146. private string baseName;
  147. private ObjectState objectState;
  148. private Base originalComponent;
  149. private string alias;
  150. private Report report;
  151. private int zOrder;
  152. #endregion
  153. #region Properties
  154. /// <summary>
  155. /// Gets or sets the name of the object.
  156. /// </summary>
  157. /// <remarks>
  158. /// <para>Name of the report object must contain alpha, digit, underscore symbols only.
  159. /// Data objects such as <b>Variable</b>, <b>TableDataSource</b>
  160. /// etc. can have any characters in they names. Each component must have unique
  161. /// name.</para>
  162. /// </remarks>
  163. /// <example>The following code demonstrates how to find an object by its name:
  164. /// <code>
  165. /// TextObject text1 = report1.FindObject("Text1") as TextObject;
  166. /// </code>
  167. /// </example>
  168. /// <exception cref="DuplicateNameException" caption="">Another object with such name exists.</exception>
  169. /// <exception cref="AncestorException" caption="">Rename an object that was introduced in the ancestor report.</exception>
  170. [MergableProperty(false)]
  171. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  172. [Category("Design")]
  173. [DisplayName("(Name)")]
  174. public virtual string Name
  175. {
  176. get { return name; }
  177. set
  178. {
  179. if (String.Compare(name, value, true) == 0)
  180. return;
  181. if (value != "" && Report != null && HasFlag(Flags.HasGlobalName))
  182. {
  183. Base c = Report.FindObject(value);
  184. if (c != null && c != this)
  185. throw new DuplicateNameException(value);
  186. if (IsAncestor)
  187. throw new AncestorException(name);
  188. if (IsDesigning)
  189. CheckValidIdent(value);
  190. }
  191. SetName(value);
  192. }
  193. }
  194. /// <summary>
  195. /// Gets or sets the flags that restrict some actions in the designer.
  196. /// </summary>
  197. /// <remarks>
  198. /// Use this property to restrict some user actions like move, resize, edit, delete. For example, if
  199. /// <b>Restriction.DontMove</b> flag is set, user cannot move the object in the designer.
  200. /// </remarks>
  201. [DefaultValue(Restrictions.None)]
  202. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  203. [Category("Design")]
  204. [Editor("FastReport.TypeEditors.FlagsEditor, FastReport", typeof(UITypeEditor))]
  205. public Restrictions Restrictions
  206. {
  207. get { return restrictions; }
  208. set { restrictions = value; }
  209. }
  210. /// <summary>
  211. /// Gets the flags that allow some functionality in the designer.
  212. /// </summary>
  213. /// <remarks>
  214. /// Use this property only if you developing a new FastReport object.
  215. /// </remarks>
  216. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  217. public Flags Flags
  218. {
  219. get { return flags; }
  220. }
  221. /// <summary>
  222. /// Gets or sets the parent of the object.
  223. /// </summary>
  224. /// <remarks>
  225. /// <para>Each report object must have a parent in order to appear in the report. Parent must be able to
  226. /// contain objects of such type.</para>
  227. /// <para>Another way (preferred) to set a parent is to use specific properties of the parent object.
  228. /// For example, the <see cref="Report"/> object has the <see cref="FastReport.Report.Pages"/> collection.
  229. /// To add a new page to the report, use the following code: <c>report1.Pages.Add(new ReportPage());</c>
  230. /// </para>
  231. /// </remarks>
  232. /// <example><code>
  233. /// Report report1;
  234. /// ReportPage page = new ReportPage();
  235. /// page.Parent = report1;
  236. /// </code></example>
  237. /// <exception cref="ParentException" caption="">Parent object cannot contain this object.</exception>
  238. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  239. public Base Parent
  240. {
  241. get { return parent; }
  242. set
  243. {
  244. if (value != parent)
  245. {
  246. if (value != null)
  247. {
  248. if (value is IParent)
  249. (value as IParent).AddChild(this);
  250. }
  251. else
  252. {
  253. (parent as IParent).RemoveChild(this);
  254. }
  255. }
  256. }
  257. }
  258. /// <summary>
  259. /// The base part of the object's name.
  260. /// </summary>
  261. /// <remarks>
  262. /// This property is used to automatically create unique object's name. See <see cref="CreateUniqueName"/>
  263. /// </remarks>
  264. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  265. public string BaseName
  266. {
  267. get { return baseName; }
  268. set { baseName = value; }
  269. }
  270. /// <summary>
  271. /// Gets the short type name.
  272. /// </summary>
  273. /// <remarks>
  274. /// Returns the short type name, such as "TextObject".
  275. /// </remarks>
  276. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  277. public string ClassName
  278. {
  279. get { return GetType().Name; }
  280. }
  281. /// <summary>
  282. /// Gets reference to the parent <see cref="Report"/> object.
  283. /// </summary>
  284. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  285. public Report Report
  286. {
  287. get
  288. {
  289. if (this is Report)
  290. return this as Report;
  291. if (report != null)
  292. return report;
  293. if (Parent != null)
  294. return Parent.Report;
  295. return null;
  296. }
  297. }
  298. /// <summary>
  299. /// Gets reference to the parent <see cref="PageBase"/> object.
  300. /// </summary>
  301. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  302. public PageBase Page
  303. {
  304. get
  305. {
  306. if (this is PageBase)
  307. return (PageBase)this;
  308. Base c = Parent;
  309. while (c != null)
  310. {
  311. if (c is PageBase)
  312. return (PageBase)c;
  313. c = c.Parent;
  314. }
  315. return null;
  316. }
  317. }
  318. /// <summary>
  319. /// Gets the collection of this object's child objects.
  320. /// </summary>
  321. /// <remarks>
  322. /// This property returns child objects that belongs to this object. For example, <b>Report.ChildObjects</b>
  323. /// will return only pages that contains in the report, but not page childs such as bands. To return all
  324. /// child objects, use <see cref="AllObjects"/> property.
  325. /// </remarks>
  326. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  327. public ObjectCollection ChildObjects
  328. {
  329. get
  330. {
  331. ObjectCollection result = new ObjectCollection();
  332. if (this is IParent)
  333. (this as IParent).GetChildObjects(result);
  334. return result;
  335. }
  336. }
  337. /// <summary>
  338. /// Gets the collection of all child objects.
  339. /// </summary>
  340. /// <remarks>
  341. /// This property returns child objects that belongs to this object and to child objects of this object.
  342. /// For example, <b>Report.AllObjects</b> will return all objects that contains in the report - such as
  343. /// pages, bands, text objects.
  344. /// </remarks>
  345. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  346. public ObjectCollection AllObjects
  347. {
  348. get
  349. {
  350. ObjectCollection result = new ObjectCollection();
  351. EnumObjects(this, result);
  352. return result;
  353. }
  354. }
  355. /// <summary>
  356. /// Gets or sets the Z-order of the object.
  357. /// </summary>
  358. /// <remarks>
  359. /// The Z-order is also called "creation order". It is the index of an object in the parent's objects list.
  360. /// For example, put two text objects on a band. First object will have <b>ZOrder</b> = 0, second = 1. Setting the
  361. /// second object's <b>ZOrder</b> to 0 will move it to the back of the first text object.
  362. /// </remarks>
  363. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  364. public int ZOrder
  365. {
  366. get
  367. {
  368. if (parent != null)
  369. return (parent as IParent).GetChildOrder(this);
  370. return zOrder;
  371. }
  372. set
  373. {
  374. if (parent != null)
  375. (parent as IParent).SetChildOrder(this, value);
  376. else
  377. zOrder = value;
  378. }
  379. }
  380. /// <summary>
  381. /// Gets a value indicating whether the object was introduced in the ancestor report.
  382. /// </summary>
  383. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  384. public bool IsAncestor
  385. {
  386. get { return GetObjectState(ObjectState.IsAncestor); }
  387. }
  388. /// <summary>
  389. /// Gets a value indicating whether the object is in the design state.
  390. /// </summary>
  391. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  392. public bool IsDesigning
  393. {
  394. get { return GetObjectState(ObjectState.IsDesigning); }
  395. }
  396. /// <summary>
  397. /// Gets a value indicating whether the object is currently printing.
  398. /// </summary>
  399. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  400. public bool IsPrinting
  401. {
  402. get { return GetObjectState(ObjectState.IsPrinting); }
  403. }
  404. /// <summary>
  405. /// Gets a value indicating whether the object is currently processed by the report engine.
  406. /// </summary>
  407. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  408. public bool IsRunning
  409. {
  410. get { return GetObjectState(ObjectState.IsRunning); }
  411. }
  412. /// <summary>
  413. /// Gets a value indicating whether the object is currently processed by the report engine.
  414. /// </summary>
  415. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  416. internal bool IsDeserializing
  417. {
  418. get { return GetObjectState(ObjectState.IsDeserializing); }
  419. set { SetObjectState(ObjectState.IsDeserializing, value); }
  420. }
  421. /// <summary>
  422. /// Gets an original component for this object.
  423. /// </summary>
  424. /// <remarks>
  425. /// This property is used in the preview mode. Each object in the prepared report is bound to its
  426. /// original (from the report template). This technique is used to minimize the prepared report's size.
  427. /// </remarks>
  428. [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  429. public Base OriginalComponent
  430. {
  431. get { return originalComponent; }
  432. set { originalComponent = value; }
  433. }
  434. internal string Alias
  435. {
  436. get { return alias; }
  437. set { alias = value; }
  438. }
  439. #endregion
  440. #region Private Methods
  441. private void CheckValidIdent(string value)
  442. {
  443. if (!CodeGenerator.IsValidLanguageIndependentIdentifier(value))
  444. throw new NotValidIdentifierException(value);
  445. }
  446. private void EnumObjects(Base c, ObjectCollection list)
  447. {
  448. if (c != this)
  449. list.Add(c);
  450. foreach (Base obj in c.ChildObjects)
  451. EnumObjects(obj, list);
  452. }
  453. #endregion
  454. #region Protected Methods
  455. /// <summary>
  456. /// Helper method, helps to set a reference-type value to the property.
  457. /// </summary>
  458. /// <param name="prop">Old property value.</param>
  459. /// <param name="value">New property value.</param>
  460. /// <remarks>
  461. /// This method is used widely to set a new value to the property that references another FastReport object.
  462. /// Method deals with the <see cref="Parent"/> property.
  463. /// </remarks>
  464. /// <example>This is example of the <c>DataBand.Header</c> property:<code>
  465. /// public DataHeaderBand Header
  466. /// {
  467. /// get { return FHeader; }
  468. /// set
  469. /// {
  470. /// SetProp(FHeader, value);
  471. /// FHeader = value;
  472. /// }
  473. /// }
  474. /// </code></example>
  475. protected void SetProp(Base prop, Base value)
  476. {
  477. if (prop != value)
  478. {
  479. if (prop != null)
  480. prop.SetParent(null);
  481. if (value != null)
  482. {
  483. value.Parent = null;
  484. value.SetParent(this);
  485. }
  486. }
  487. }
  488. /// <summary>
  489. /// Checks if two float values are different.
  490. /// </summary>
  491. /// <param name="f1">First value.</param>
  492. /// <param name="f2">Second value.</param>
  493. /// <returns><c>true</c> if values are not equal.</returns>
  494. /// <remarks>
  495. /// This method is needed to compare two float values using some precision (0.001). It is useful
  496. /// to compare objects' locations and sizes for equality.
  497. /// </remarks>
  498. protected bool FloatDiff(float f1, float f2)
  499. {
  500. return Math.Abs(f1 - f2) > 0.001;
  501. }
  502. /// <summary>
  503. /// Deserializes nested object properties.
  504. /// </summary>
  505. /// <param name="reader">Reader object.</param>
  506. /// <remarks>
  507. /// <para>Typically the object serializes all properties to the single xml item:</para>
  508. /// <code>
  509. /// &lt;TextObject Name="Text2" Left="18.9" Top="37.8" Width="283.5" Height="28.35"/&gt;
  510. /// </code>
  511. /// <para>Some objects like <see cref="DataBand"/> have child objects that serialized in subitems:</para>
  512. /// <code>
  513. /// &lt;DataBand Name="Data1" Top="163" Width="718.2" Height="18.9"&gt;
  514. /// &lt;TextObject Name="Text3" Left="18.9" Top="37.8" Width="283.5" Height="28.35"/&gt;
  515. /// &lt;/DataBand&gt;
  516. /// </code>
  517. /// <para>To read such subitems, the <c>DeserializeSubItems</c> method is used. Base
  518. /// implementation reads the child objects. You may override it to read some specific subitems.</para>
  519. /// </remarks>
  520. /// <example>The following code is used to read report's styles:
  521. /// <code>
  522. /// protected override void DeserializeSubItems(FRReader reader)
  523. /// {
  524. /// if (String.Compare(reader.ItemName, "Styles", true) == 0)
  525. /// reader.Read(Styles);
  526. /// else
  527. /// base.DeserializeSubItems(reader);
  528. /// }
  529. /// </code>
  530. /// </example>
  531. protected virtual void DeserializeSubItems(FRReader reader)
  532. {
  533. if (reader.ReadChildren)
  534. {
  535. Base obj = reader.Read() as Base;
  536. if (obj != null)
  537. {
  538. obj.Parent = this;
  539. if (IsAncestor && !obj.IsAncestor)
  540. obj.ZOrder = obj.zOrder;
  541. }
  542. }
  543. }
  544. /// <summary>
  545. /// Replaces the macros in the given string and returns the new string.
  546. /// </summary>
  547. /// <param name="text">The text containing macros.</param>
  548. /// <returns>The text with macros replaced with its values.</returns>
  549. protected string ExtractDefaultMacros(string text)
  550. {
  551. Dictionary<string, object> macroValues = Report.PreparedPages.MacroValues;
  552. text = ExtractDefaultMacrosInternal(macroValues, text);
  553. text = text.Replace("[TOTALPAGES#]", macroValues["TotalPages#"].ToString());
  554. text = text.Replace("[PAGE#]", macroValues["Page#"].ToString());
  555. return text;
  556. }
  557. /// <inheritdoc/>
  558. protected override void Dispose(bool disposing)
  559. {
  560. if (disposing)
  561. {
  562. Clear();
  563. Parent = null;
  564. }
  565. base.Dispose(disposing);
  566. }
  567. #endregion
  568. #region Public Methods
  569. /// <summary>
  570. /// Set object's flags.
  571. /// </summary>
  572. /// <param name="flags">Flag to set.</param>
  573. /// <param name="value"><b>true</b> to set the flag, <b>false</b> to reset.</param>
  574. public void SetFlags(Flags flags, bool value)
  575. {
  576. if (value)
  577. this.flags |= flags;
  578. else
  579. this.flags &= ~flags;
  580. }
  581. private bool GetObjectState(ObjectState state)
  582. {
  583. return (objectState & state) > 0;
  584. }
  585. private void SetObjectState(ObjectState state, bool value)
  586. {
  587. if (value)
  588. this.objectState |= state;
  589. else
  590. this.objectState &= ~state;
  591. }
  592. internal void SetAncestor(bool value)
  593. {
  594. SetObjectState(ObjectState.IsAncestor, value);
  595. }
  596. internal void SetDesigning(bool value)
  597. {
  598. SetObjectState(ObjectState.IsDesigning, value);
  599. }
  600. internal void SetPrinting(bool value)
  601. {
  602. SetObjectState(ObjectState.IsPrinting, value);
  603. }
  604. internal void SetRunning(bool value)
  605. {
  606. SetObjectState(ObjectState.IsRunning, value);
  607. }
  608. /// <summary>
  609. /// Sets the reference to a Report.
  610. /// </summary>
  611. /// <param name="value">Report to set.</param>
  612. public void SetReport(Report value)
  613. {
  614. report = value;
  615. }
  616. /// <summary>
  617. /// Sets the object's name.
  618. /// </summary>
  619. /// <remarks>
  620. /// This method is for internal use only. It just sets a new name without any checks
  621. /// (unlike the <see cref="Name"/> property setter).
  622. /// </remarks>
  623. /// <seealso cref="Name">Name Property</seealso>
  624. /// <param name="value">New name.</param>
  625. public virtual void SetName(string value)
  626. {
  627. name = value;
  628. }
  629. /// <summary>
  630. /// Sets the object's parent.
  631. /// </summary>
  632. /// <remarks>
  633. /// This method is for internal use only. You can use it if you are developing a new
  634. /// component for FastReport. Override it to perform some actions when the parent of an
  635. /// object is changing. This method checks that parent can contain a child.
  636. /// </remarks>
  637. /// <exception cref="ParentException" caption="">Parent object cannot contain this object.</exception>
  638. /// <param name="value">New parent.</param>
  639. public virtual void SetParent(Base value)
  640. {
  641. if (value != null)
  642. if (!(value is IParent) || !(value as IParent).CanContain(this))
  643. throw new ParentException(value, this);
  644. SetParentCore(value);
  645. }
  646. /// <summary>
  647. /// Sets the object's parent.
  648. /// </summary>
  649. /// <param name="value">New parent.</param>
  650. /// <remarks>
  651. /// This method is for internal use only. You can use it if you are developing a new component for FastReport.
  652. /// This method does not perform any checks, it just sets the new parent.
  653. /// </remarks>
  654. public void SetParentCore(Base value)
  655. {
  656. parent = value;
  657. }
  658. /// <summary>
  659. /// Searches for an object with given name.
  660. /// </summary>
  661. /// <param name="name">Name of the object to find.</param>
  662. /// <returns>Returns a null reference if object is not found</returns>
  663. /// <example>The following code demonstrates how to find an object by its name:
  664. /// <code>
  665. /// TextObject text1 = report1.FindObject("Text1") as TextObject;
  666. /// if (text1 != null)
  667. /// {
  668. /// // object found
  669. /// }
  670. /// </code>
  671. /// </example>
  672. public virtual Base FindObject(string name)
  673. {
  674. ObjectCollection l = AllObjects;
  675. foreach (Base c in l)
  676. {
  677. if (name == c.Name)
  678. return c;
  679. }
  680. return null;
  681. }
  682. /// <summary>
  683. /// Creates the unique object's name.
  684. /// </summary>
  685. /// <remarks>
  686. /// <para><b>Note:</b> you have to set object's parent before calling this method. Method uses the <see cref="BaseName"/>
  687. /// property to create a name.</para>
  688. /// <para><b>Note:</b> this method may be very slow on a report that contains lots of objects. Consider
  689. /// using own naming logic in this case.</para>
  690. /// </remarks>
  691. /// <example>
  692. /// <code>
  693. /// TextObject textObj = new TextObject();
  694. /// dataBand1.Objects.Add(textObj);
  695. /// textObj.CreateUniqueName();
  696. /// </code>
  697. /// </example>
  698. public void CreateUniqueName()
  699. {
  700. Report report = Report;
  701. if (report == null)
  702. return;
  703. string s;
  704. int i = 1;
  705. do
  706. {
  707. s = baseName + i.ToString();
  708. i++;
  709. }
  710. while (report.FindObject(s) != null);
  711. SetName(s);
  712. }
  713. /// <summary>
  714. /// Clears the object's state.
  715. /// </summary>
  716. /// <remarks>
  717. /// This method also disposes all object's children.
  718. /// </remarks>
  719. public virtual void Clear()
  720. {
  721. ObjectCollection list = ChildObjects;
  722. foreach (Base c in list)
  723. {
  724. c.Clear();
  725. c.Dispose();
  726. }
  727. }
  728. /// <summary>
  729. /// Serializes the object.
  730. /// </summary>
  731. /// <remarks>
  732. /// <para>Do not call this method directly. You should override it if you are
  733. /// developing a new component for FastReport.</para>
  734. /// <para>This method is called when the object needs to save the state. It may happen
  735. /// when:</para>
  736. /// <list type="bullet">
  737. /// <item>
  738. /// <description>saving the report to the file or stream;</description>
  739. /// </item>
  740. /// <item>
  741. /// <description>saving the report to the designer's undo buffer;</description>
  742. /// </item>
  743. /// <item>
  744. /// <description>
  745. /// assigning the object to another object using the
  746. /// <see cref="Assign"/> or <see cref="AssignAll(Base)">AssignAll</see> methods;
  747. /// </description>
  748. /// </item>
  749. /// <item>
  750. /// <description>saving the object to the designer's clipboard;</description>
  751. /// </item>
  752. /// <item>
  753. /// <description>saving the object to the preview (when run a
  754. /// report).</description>
  755. /// </item>
  756. /// </list>
  757. /// </remarks>
  758. /// <param name="writer">Writer object.</param>
  759. public virtual void Serialize(FRWriter writer)
  760. {
  761. Base c = writer.DiffObject as Base;
  762. if (writer.SerializeTo != SerializeTo.Preview)
  763. {
  764. // in the preview mode we don't need to write ItemName and Name properties. Alias is written instead.
  765. writer.ItemName = IsAncestor &&
  766. (writer.SerializeTo == SerializeTo.Report || writer.SerializeTo == SerializeTo.Undo) ?
  767. "inherited" : ClassName;
  768. if (Name != "")
  769. writer.WriteStr("Name", Name);
  770. if (Restrictions != c.Restrictions)
  771. writer.WriteValue("Restrictions", Restrictions);
  772. if ((writer.SerializeTo == SerializeTo.Report || writer.SerializeTo == SerializeTo.Undo) &&
  773. !IsAncestor && Parent != null && Parent.IsAncestor)
  774. writer.WriteInt("ZOrder", ZOrder);
  775. }
  776. if (writer.SaveChildren)
  777. {
  778. foreach (Base child in ChildObjects)
  779. {
  780. writer.Write(child);
  781. }
  782. }
  783. }
  784. /// <summary>
  785. /// Deserializes the object.
  786. /// </summary>
  787. /// <remarks>
  788. /// <para>Do not call this method directly. You should override it if you are
  789. /// developing a new component for FastReport.</para>
  790. /// <para>This method is called when the object needs to restore the state. It may
  791. /// happen when:</para>
  792. /// <list type="bullet">
  793. /// <item>
  794. /// <description>loading the report from a file or stream;</description>
  795. /// </item>
  796. /// <item>
  797. /// <description>loading the report from the designer's undo
  798. /// buffer;</description>
  799. /// </item>
  800. /// <item>
  801. /// <description>assigning another object to this object using the
  802. /// <see cref="Assign"/> or <see cref="AssignAll(Base)">AssignAll</see> methods;</description>
  803. /// </item>
  804. /// <item>
  805. /// <description>loading the object from the designer's
  806. /// clipboard;</description>
  807. /// </item>
  808. /// <item>loading the object from the preview pages.</item>
  809. /// </list>
  810. /// </remarks>
  811. /// <param name="reader">Reader object.</param>
  812. public virtual void Deserialize(FRReader reader)
  813. {
  814. try
  815. {
  816. IsDeserializing = true;
  817. reader.ReadProperties(this);
  818. while (reader.NextItem())
  819. {
  820. DeserializeSubItems(reader);
  821. }
  822. }
  823. finally
  824. {
  825. IsDeserializing = false;
  826. }
  827. }
  828. /// <summary>
  829. /// Assigns values from another source.
  830. /// </summary>
  831. /// <remarks>
  832. /// <b>Note:</b> this method is relatively slow because it serializes
  833. /// an object to the xml and then deserializes it.
  834. /// </remarks>
  835. /// <param name="source">Source to assign from.</param>
  836. public void BaseAssign(Base source)
  837. {
  838. bool saveAncestor = source.IsAncestor;
  839. source.SetAncestor(false);
  840. try
  841. {
  842. using (XmlItem xml = new XmlItem())
  843. using (FRWriter writer = new FRWriter(xml))
  844. using (FRReader reader = new FRReader(Report, xml))
  845. {
  846. writer.SaveChildren = false;
  847. writer.Write(source, this);
  848. reader.Read(this);
  849. }
  850. Alias = source.Alias;
  851. OriginalComponent = source.OriginalComponent;
  852. }
  853. finally
  854. {
  855. source.SetAncestor(saveAncestor);
  856. }
  857. }
  858. /// <summary>Copies the contents of another, similar object.</summary>
  859. /// <remarks>
  860. /// <para>Call Assign to copy the properties from another object of the same type.
  861. /// The standard form of a call to Assign is</para>
  862. /// <para><c>destination.Assign(source);</c></para>
  863. /// <para>
  864. /// which tells the <b>destination</b> object to copy the contents of the
  865. /// <b>source</b> object to itself. In this method, all child objects are
  866. /// ignored. If you want to copy child objects, use the
  867. /// <see cref="AssignAll(Base)">AssignAll</see> method.
  868. /// </para>
  869. /// </remarks>
  870. /// <example><code>
  871. /// Report report1;
  872. /// Report report2 = new Report();
  873. /// // copy all report settings, do not copy report objects
  874. /// report2.Assign(report1);
  875. /// </code></example>
  876. /// <seealso cref="AssignAll(Base)">AssignAll Method</seealso>
  877. /// <param name="source">Source object to copy the contents from.</param>
  878. public virtual void Assign(Base source)
  879. {
  880. Restrictions = source.Restrictions;
  881. Alias = source.Alias;
  882. OriginalComponent = source.OriginalComponent;
  883. }
  884. /// <summary>Copies the contents (including children) of another, similar object.</summary>
  885. /// <remarks>
  886. /// <para>
  887. /// This method is similar to <see cref="Assign"/> method. It copies child
  888. /// objects as well.
  889. /// </para>
  890. /// </remarks>
  891. /// <example><code>
  892. /// Report report1;
  893. /// Report report2 = new Report();
  894. /// // copy all report settings and objects
  895. /// report2.AssignAll(report1);
  896. /// </code></example>
  897. /// <seealso cref="Assign"/>
  898. /// <param name="source">Source object to copy the state from.</param>
  899. public void AssignAll(Base source)
  900. {
  901. AssignAll(source, false);
  902. }
  903. internal void AssignAll(Base source, bool assignName)
  904. {
  905. Clear();
  906. Assign(source);
  907. if (assignName)
  908. SetName(source.Name);
  909. foreach (Base child in source.ChildObjects)
  910. {
  911. Base myChild = Activator.CreateInstance(child.GetType()) as Base;
  912. myChild.SetReport(Report);
  913. myChild.AssignAll(child, assignName);
  914. myChild.SetReport(null);
  915. myChild.Parent = this;
  916. }
  917. }
  918. /// <summary>
  919. /// Gets a value indicating whether the object has the specified parent in its parent hierarchy.
  920. /// </summary>
  921. /// <param name="obj">Parent object to check.</param>
  922. /// <returns>Returns <b>true</b> if the object has given parent in its parent hierarchy.</returns>
  923. public bool HasParent(Base obj)
  924. {
  925. Base parent = Parent;
  926. while (parent != null)
  927. {
  928. if (parent == obj)
  929. return true;
  930. parent = parent.Parent;
  931. }
  932. return false;
  933. }
  934. /// <summary>
  935. /// Gets a value indicating whether the object has a specified flag in its <see cref="Flags"/> property.
  936. /// </summary>
  937. /// <param name="flag">Flag to check.</param>
  938. /// <returns><b>true</b> if <b>Flags</b> property contains specified flag.</returns>
  939. public bool HasFlag(Flags flag)
  940. {
  941. return (Flags & flag) > 0;
  942. }
  943. /// <summary>
  944. /// Gets a value indicating whether the object has a specified restriction
  945. /// in its <see cref="Restrictions"/> property.
  946. /// </summary>
  947. /// <param name="restriction">Restriction to check.</param>
  948. /// <returns><b>true</b> if <b>Restrictions</b> property contains specified restriction.</returns>
  949. public bool HasRestriction(Restrictions restriction)
  950. {
  951. return (Restrictions & restriction) > 0;
  952. }
  953. /// <summary>
  954. /// Invokes script event.
  955. /// </summary>
  956. /// <param name="name">Name of the event to invoke.</param>
  957. /// <param name="param">Event parameters.</param>
  958. /// <remarks>
  959. /// <para>Do not call this method directly. You should use it if you are developing a new component
  960. /// for FastReport.</para>
  961. /// <para>Use this method to call an event handler that is located in the report's script.</para>
  962. /// </remarks>
  963. /// <example>Example of the OnBeforePrint method:<code>
  964. /// public void OnBeforePrint(EventArgs e)
  965. /// {
  966. /// if (BeforePrint != null)
  967. /// BeforePrint(this, e);
  968. /// InvokeEvent(BeforePrintEvent, e);
  969. /// }
  970. /// </code></example>
  971. public void InvokeEvent(string name, object param)
  972. {
  973. if (String.IsNullOrEmpty(name))
  974. return;
  975. Report report = Report;
  976. if (report != null)
  977. report.InvokeMethod(name, new object[] { this, param });
  978. }
  979. /// <summary>
  980. /// Called after all report objects were loaded.
  981. /// </summary>
  982. /// <remarks>
  983. /// Do not call this method directly. You may override it if you are developing a new component
  984. /// for FastReport.
  985. /// </remarks>
  986. public virtual void OnAfterLoad()
  987. {
  988. }
  989. /// <summary>
  990. /// Gets all expressions contained in the object.
  991. /// </summary>
  992. /// <returns>Array of expressions or <b>null</b> if object contains no expressions.</returns>
  993. /// <remarks>
  994. /// <para>Do not call this method directly. You may override it if you are developing a
  995. /// new component for FastReport.</para>
  996. /// <para>
  997. /// This method is called by FastReport each time before run a report. FastReport
  998. /// do this to collect all expressions and compile them. For example,
  999. /// <b>GetExpressions</b> method of the <see cref="TextObject"/> class
  1000. /// parses the text and returns all expressions found in the text.
  1001. /// </para>
  1002. /// </remarks>
  1003. public virtual string[] GetExpressions()
  1004. {
  1005. return null;
  1006. }
  1007. /// <summary>
  1008. /// Returns a custom code that will be added to the report script before report is run.
  1009. /// </summary>
  1010. /// <returns>A custom script text, if any. Otherwise returns <b>null</b>.</returns>
  1011. /// <remarks>
  1012. /// <para>This method may return any valid code that may be inserted into the report script. Currently it is
  1013. /// used in the TableObject to define the following script methods: Sum, Min, Max, Avg, Count.
  1014. /// </para>
  1015. /// <para>
  1016. /// Note: you must take into account the current script language - C# or VB.Net. You may check it via
  1017. /// <b>Report.ScriptLanguage</b> property.
  1018. /// </para>
  1019. /// </remarks>
  1020. public virtual string GetCustomScript()
  1021. {
  1022. return null;
  1023. }
  1024. /// <summary>
  1025. /// Used to extract macros such as "TotalPages#" in the preview mode.
  1026. /// </summary>
  1027. /// <remarks>
  1028. /// This method is used mainly by the <b>TextObject</b> to extract macros and replace it with
  1029. /// actual values passed in the <b>pageIndex</b> and <b>totalPages</b> parameters. This method
  1030. /// is called automatically when the object is being previewed.
  1031. /// </remarks>
  1032. public virtual void ExtractMacros()
  1033. {
  1034. }
  1035. /// <summary>
  1036. /// Used to get information of the need to convertation if the function returns true, then the GetConvertedObjects function is called
  1037. /// </summary>
  1038. /// <param name="sender">The export or the object, that call this method</param>
  1039. /// <returns>By default returns false</returns>
  1040. /// <remarks>
  1041. /// The functions IsHaveToConvert and GetConvertedObjects allow you to convert objects from one to another,
  1042. /// for example the export will convert object before adding it to the file and convert recursive,
  1043. /// i.e. If the new object has the ability to convert,
  1044. /// it will be converted again but limit is 10 times.
  1045. /// At the time of export it is called, only on objects inside the band,
  1046. /// the child objects of converted object will be returned, and the child objects of old object will be ignored.
  1047. /// </remarks>
  1048. public virtual bool IsHaveToConvert(object sender)
  1049. {
  1050. return false;
  1051. }
  1052. /// <summary>
  1053. /// 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
  1054. /// </summary>
  1055. /// <returns>By default returns this object</returns>
  1056. /// <remarks>
  1057. /// The functions IsHaveToConvert and GetConvertedObjects allow you to convert objects from one to another,
  1058. /// for example the export will convert object before adding it to the file and convert recursive,
  1059. /// i.e. If the new object has the ability to convert,
  1060. /// it will be converted again but limit is 10 times.
  1061. /// At the time of export it is called, only on objects inside the band,
  1062. /// the child objects of converted object will be returned, and the child objects of old object will be ignored.
  1063. /// </remarks>
  1064. public virtual IEnumerable<Base> GetConvertedObjects()
  1065. {
  1066. yield return this;
  1067. }
  1068. /// <summary>
  1069. /// Gets the collection of all child objects, converts objects if necessary
  1070. /// </summary>
  1071. /// <param name="sender">the object or export, that call this convertation</param>
  1072. public ObjectCollection ForEachAllConvectedObjects(object sender)
  1073. {
  1074. ObjectCollection list = new ObjectCollection();
  1075. EnumAllConvertedObjects(sender, this, list, 0);
  1076. return list;
  1077. }
  1078. private void EnumAllConvertedObjects(object sender, Base c, ObjectCollection list, int convertValue)
  1079. {
  1080. if (c != this)
  1081. {
  1082. if (c.IsHaveToConvert(sender))
  1083. {
  1084. if (convertValue < 10)
  1085. {
  1086. foreach (Base b in c.GetConvertedObjects())
  1087. EnumAllConvertedObjects(sender, b, list, convertValue + 1);
  1088. return;
  1089. }
  1090. }
  1091. list.Add(c);
  1092. }
  1093. foreach (Base obj in c.ChildObjects)
  1094. EnumAllConvertedObjects(sender, obj, list, convertValue);
  1095. }
  1096. #endregion
  1097. /// <summary>
  1098. /// Initializes a new instance of the <b>Base</b> class with default settings.
  1099. /// </summary>
  1100. public Base()
  1101. {
  1102. name = "";
  1103. alias = "";
  1104. baseName = ClassName;
  1105. restrictions = new Restrictions();
  1106. SetFlags(Flags.CanMove | Flags.CanResize | Flags.CanDelete | Flags.CanEdit | Flags.CanChangeOrder |
  1107. Flags.CanChangeParent | Flags.CanCopy | Flags.CanDraw | Flags.CanShowChildrenInReportTree, true);
  1108. }
  1109. }
  1110. }