Base.cs 42 KB

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