PageRenderTime 46ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/AODL/Document/Content/Text/Paragraph.cs

https://bitbucket.org/chrisc/aodl
C# | 764 lines | 411 code | 98 blank | 255 comment | 130 complexity | c6d726508ec12cff390b2c82e08dcbc7 MD5 | raw file
  1. /*************************************************************************
  2. *
  3. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
  4. *
  5. * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
  6. *
  7. * Use is subject to license terms.
  8. *
  9. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  10. * use this file except in compliance with the License. You may obtain a copy
  11. * of the License at http://www.apache.org/licenses/LICENSE-2.0. You can also
  12. * obtain a copy of the License at http://odftoolkit.org/docs/license.txt
  13. *
  14. * Unless required by applicable law or agreed to in writing, software
  15. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  16. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. *
  18. * See the License for the specific language governing permissions and
  19. * limitations under the License.
  20. *
  21. ************************************************************************/
  22. using System;
  23. using System.Collections.Generic;
  24. using System.Linq;
  25. using System.Xml.Linq;
  26. using AODL.Document.Import.OpenDocument.NodeProcessors;
  27. using AODL.Document.Styles;
  28. using AODL.Document.TextDocuments;
  29. namespace AODL.Document.Content.Text
  30. {
  31. /// <summary>
  32. /// Represent a paragraph within a opendocument document.
  33. /// </summary>
  34. public class Paragraph : IContent, IContentContainer, IHtml, ITextContainer, ICloneable
  35. {
  36. /// <summary>
  37. /// Mixed content - needed for alternative
  38. /// exporter implementations. In OpenDocument
  39. /// the order will be right automatically.
  40. /// </summary>
  41. private readonly ParentStyles _parentStyle;
  42. private IList<IContent> _mixedContent;
  43. /// <summary>
  44. /// Initializes a new instance of the <see cref="Paragraph"/> class.
  45. /// This is a blank paragraph.
  46. /// </summary>
  47. /// <param name="document">The document.</param>
  48. public Paragraph(IDocument document)
  49. {
  50. Document = document;
  51. Node = new XElement(Ns.Text + "p");
  52. InitStandards();
  53. }
  54. /// <summary>
  55. /// Create a new Paragraph object.
  56. /// </summary>
  57. /// <param name="document">The Texdocumentocument.</param>
  58. /// <param name="styleName">The styleName which should be referenced with this paragraph.</param>
  59. public Paragraph(IDocument document, string styleName)
  60. {
  61. Document = document;
  62. Node = new XElement(Ns.Text + "p");
  63. Init(styleName);
  64. }
  65. /// <summary>
  66. /// Overloaded constructor.
  67. /// Use this to create a standard paragraph with the given text from
  68. /// string simpletext. Notice, the text will be styled as standard.
  69. /// You won't be able to style it bold, underline, etc. this will only
  70. /// occur if standard style attributes of the texdocumentocument are set to
  71. /// this.
  72. /// </summary>
  73. /// <param name="document">The IDocument.</param>
  74. /// <param name="style">The only accepted ParentStyle is Standard! All other styles will be ignored!</param>
  75. /// <param name="simpletext">The text which should be append within this paragraph.</param>
  76. public Paragraph(IDocument document, ParentStyles style, string simpletext)
  77. {
  78. Document = document;
  79. Node = new XElement(Ns.Text + "p");
  80. if (style == ParentStyles.Standard)
  81. Init(ParentStyles.Standard.ToString());
  82. else if (style == ParentStyles.Table)
  83. Init(ParentStyles.Table.ToString());
  84. else if (style == ParentStyles.Text_20_body)
  85. Init(ParentStyles.Text_20_body.ToString());
  86. //Attach simple text withhin the paragraph
  87. if (simpletext != null)
  88. TextContent.Add(new SimpleText(Document, simpletext));
  89. _parentStyle = style;
  90. }
  91. /// <summary>
  92. /// Initializes a new instance of the <see cref="Paragraph"/> class.
  93. /// </summary>
  94. /// <param name="node">The node.</param>
  95. /// <param name="document">The document.</param>
  96. public Paragraph(XElement node, IDocument document)
  97. {
  98. Document = document;
  99. Node = node;
  100. InitStandards();
  101. }
  102. /// <summary>
  103. /// Gets the content of the mixed.
  104. /// </summary>
  105. /// <value>The content of the mixed.</value>
  106. public IList<IContent> MixedContent
  107. {
  108. get { return _mixedContent; }
  109. }
  110. /// <summary>
  111. /// Gets the parent style.
  112. /// </summary>
  113. /// <value>The parent style.</value>
  114. public ParentStyles ParentStyle
  115. {
  116. get { return _parentStyle; }
  117. }
  118. /// <summary>
  119. /// Gets or sets the paragraph style.
  120. /// </summary>
  121. /// <value>The paragraph style.</value>
  122. public ParagraphStyle ParagraphStyle
  123. {
  124. get { return (ParagraphStyle) Style; }
  125. set { Style = value; }
  126. }
  127. /// <summary>
  128. /// Create the Paragraph.
  129. /// </summary>
  130. /// <param name="styleName">The style name.</param>
  131. private void Init(string styleName)
  132. {
  133. if (styleName != "Standard"
  134. && styleName != "Table_20_Contents"
  135. && styleName != "Text_20_body")
  136. {
  137. Style = new ParagraphStyle(Document, styleName);
  138. Document.Styles.Add(Style);
  139. }
  140. InitStandards();
  141. StyleName = styleName;
  142. }
  143. /// <summary>
  144. /// Inits the standards.
  145. /// </summary>
  146. private void InitStandards()
  147. {
  148. TextContent = new ITextCollection();
  149. Content = new ContentCollection();
  150. _mixedContent = new List<IContent>();
  151. if (Document is TextDocument)
  152. Document.DocumentMetadata.ParagraphCount += 1;
  153. TextContent.Inserted += TextContent_Inserted;
  154. Content.Inserted += Content_Inserted;
  155. TextContent.Removed += TextContent_Removed;
  156. Content.Removed += Content_Removed;
  157. }
  158. /// <summary>
  159. /// Append the xml from added IText object.
  160. /// </summary>
  161. /// <param name="index"></param>
  162. /// <param name="value"></param>
  163. private void TextContent_Inserted(int index, object value)
  164. {
  165. Node.Add(((IText) value).Node);
  166. _mixedContent.Add((IText)value);
  167. if (((IText) value).Text != null)
  168. {
  169. try
  170. {
  171. if (Document is TextDocument)
  172. {
  173. string text = ((IText) value).Text;
  174. Document.DocumentMetadata.CharacterCount += text.Length;
  175. string[] words = text.Split(' ');
  176. Document.DocumentMetadata.WordCount += words.Length;
  177. }
  178. }
  179. catch (Exception)
  180. {
  181. //unhandled, only word and character count wouldn' be correct
  182. }
  183. }
  184. }
  185. /// <summary>
  186. /// Content_s the inserted.
  187. /// </summary>
  188. /// <param name="index">The index.</param>
  189. /// <param name="value">The value.</param>
  190. private void Content_Inserted(int index, object value)
  191. {
  192. Node.Add(((IContent) value).Node);
  193. _mixedContent.Add((IContent)value);
  194. }
  195. /// <summary>
  196. /// Texts the content_ removed.
  197. /// </summary>
  198. /// <param name="index">The index.</param>
  199. /// <param name="value">The value.</param>
  200. private void TextContent_Removed(int index, object value)
  201. {
  202. ((IText) value).Node.Remove();
  203. RemoveMixedContent(value);
  204. }
  205. /// <summary>
  206. /// Content_s the removed.
  207. /// </summary>
  208. /// <param name="index">The index.</param>
  209. /// <param name="value">The value.</param>
  210. private void Content_Removed(int index, object value)
  211. {
  212. ((IContent) value).Node.Remove();
  213. RemoveMixedContent(value);
  214. }
  215. /// <summary>
  216. /// Removes the mixed content
  217. /// </summary>
  218. /// <param name="value">The value.</param>
  219. private void RemoveMixedContent(object value)
  220. {
  221. if (_mixedContent.Contains((IContent)value))
  222. _mixedContent.Remove((IContent)value);
  223. }
  224. #region IHtml Member
  225. /// <summary>
  226. /// Return the content as Html string
  227. /// </summary>
  228. /// <returns>The html string</returns>
  229. public string GetHtml()
  230. {
  231. string html = "<p ";
  232. string textStyle;
  233. bool useSpan = false;
  234. bool useGlobal = false;
  235. if (Style != null)
  236. {
  237. if (((ParagraphStyle) Style).ParentStyle == "Heading"
  238. && ParagraphStyle.ParagraphProperties == null
  239. && ParagraphStyle.TextProperties == null)
  240. useGlobal = true;
  241. else
  242. {
  243. if (ParagraphStyle.ParagraphProperties != null)
  244. html += ParagraphStyle.ParagraphProperties.GetHtmlStyle();
  245. if (ParagraphStyle.TextProperties != null)
  246. {
  247. textStyle = ParagraphStyle.TextProperties.GetHtmlStyle();
  248. if (textStyle.Length > 0)
  249. {
  250. html += "<span " + textStyle;
  251. useSpan = true;
  252. }
  253. }
  254. }
  255. }
  256. else
  257. useGlobal = true;
  258. if (useGlobal)
  259. {
  260. string global = GetHtmlStyleFromGlobalStyles();
  261. if (global.Length > 0)
  262. html += global;
  263. }
  264. html += ">\n";
  265. //There check all content if they
  266. //support HTML
  267. foreach (IContent content in _mixedContent)
  268. {
  269. if (content is IHtml)
  270. {
  271. string text = ((IHtml) content).GetHtml();
  272. html += text;
  273. }
  274. }
  275. if (useSpan)
  276. return html + "</span>&nbsp;</p>\n";
  277. return html + "&nbsp;</p>\n";
  278. // if (this.TextContent.Count > 0)
  279. // {
  280. // if (useSpan)
  281. // return html + this.GetTextHtmlContent()+"</span></p>\n";
  282. // else
  283. // return html + this.GetTextHtmlContent()+"</p>\n";
  284. // }
  285. // else
  286. // {
  287. // string text = this.GetContentHtmlContent();
  288. // text = (text!=String.Empty) ? text : "&nbsp;";
  289. //
  290. // if (useSpan)
  291. // return html + text +"</span></p>\n";
  292. // else
  293. // return html + text +"</p>\n";
  294. // }
  295. }
  296. /// <summary>
  297. /// Gets the content of the text HTML.
  298. /// </summary>
  299. /// <returns>Textcontent as Html string</returns>
  300. private string GetTextHtmlContent()
  301. {
  302. string html = "";
  303. foreach (IText itext in TextContent)
  304. {
  305. if (itext is IHtml)
  306. html += ((IHtml) itext).GetHtml() + "\n";
  307. }
  308. return html;
  309. }
  310. /// <summary>
  311. /// Gets the content of the text HTML.
  312. /// </summary>
  313. /// <returns>Textcontent as Html string</returns>
  314. private string GetContentHtmlContent()
  315. {
  316. string html = "";
  317. foreach (IContent icontent in Content)
  318. {
  319. if (icontent is IHtml)
  320. html += ((IHtml) icontent).GetHtml();
  321. }
  322. return html;
  323. }
  324. /// <summary>
  325. /// Gets the HTML style from global styles.
  326. /// This isn't supported by AODL yet. But if
  327. /// OpenDocument text documents are loaded,
  328. /// this could be.
  329. /// </summary>
  330. /// <returns>The style from Global Styles</returns>
  331. private string GetHtmlStyleFromGlobalStyles()
  332. {
  333. try
  334. {
  335. string style = "style=\"";
  336. if (Document is TextDocument)
  337. {
  338. XElement styleNode =
  339. ((TextDocument) Document).DocumentStyles.Styles.Descendants(Ns.Office + "styles")
  340. .Elements(Ns.Style + "style")
  341. .Where(e => string.Equals((string) e.Attribute(Ns.Style + "name"), StyleName)).
  342. FirstOrDefault();
  343. if (styleNode == null)
  344. styleNode = ((TextDocument) Document).DocumentStyles.Styles.Descendants(Ns.Office + "styles")
  345. .Elements(Ns.Style + "style")
  346. .Where(
  347. e =>
  348. string.Equals((string) e.Attribute(Ns.Style + "name"), ((ParagraphStyle) Style).ParentStyle))
  349. .FirstOrDefault();
  350. if (styleNode != null)
  351. {
  352. XElement paraPropNode = styleNode.Element(Ns.Style + "paragraph-properties");
  353. //Last change via parent style
  354. XAttribute parentNode = styleNode.Attribute(Ns.Style + "parent-style-name");
  355. XElement paraPropNodeP = null;
  356. XElement parentStyleNode = null;
  357. if (parentNode != null)
  358. if (parentNode.Value != null)
  359. {
  360. //Console.WriteLine("Parent-Style-Name: {0}", parentNode.InnerText);
  361. parentStyleNode =
  362. ((TextDocument) Document).DocumentStyles.Styles.Descendants(Ns.Office + "styles")
  363. .Elements(Ns.Style + "style")
  364. .Where(
  365. e => string.Equals((string) e.Attribute(Ns.Style + "name"), parentNode.Value)).
  366. FirstOrDefault();
  367. if (parentStyleNode != null)
  368. paraPropNodeP = parentStyleNode.Element(Ns.Style + "paragraph-properties");
  369. }
  370. //Check first parent style paragraph properties
  371. if (paraPropNodeP != null)
  372. {
  373. //Console.WriteLine("ParentStyleNode: {0}", parentStyleNode.OuterXml);
  374. string alignMent = (string) paraPropNodeP.Attribute(Ns.Fo + "text-align");
  375. if (alignMent != null)
  376. {
  377. alignMent = alignMent.ToLower().Replace("end", "right");
  378. if (alignMent.ToLower() == "center" || alignMent.ToLower() == "right")
  379. style += "text-align: " + alignMent + "; ";
  380. }
  381. string lineSpace = (string) paraPropNodeP.Attribute(Ns.Fo + "line-height");
  382. if (lineSpace != null)
  383. style += "line-height: " + lineSpace + "; ";
  384. string marginTop = (string) paraPropNodeP.Attribute(Ns.Fo + "margin-top");
  385. if (marginTop != null)
  386. style += "margin-top: " + marginTop + "; ";
  387. string marginBottom = (string) paraPropNodeP.Attribute(Ns.Fo + "margin-bottom");
  388. if (marginBottom != null)
  389. style += "margin-bottom: " + marginBottom + "; ";
  390. string marginLeft = (string) paraPropNodeP.Attribute(Ns.Fo + "margin-left");
  391. if (marginLeft != null)
  392. style += "margin-left: " + marginLeft + "; ";
  393. string marginRight = (string) paraPropNodeP.Attribute(Ns.Fo + "margin-right");
  394. if (marginRight != null)
  395. style += "margin-right: " + marginRight + "; ";
  396. }
  397. //Check paragraph properties, maybe parents style is overwritten or extended
  398. if (paraPropNode != null)
  399. {
  400. string alignMent = (string) paraPropNode.Attribute(Ns.Fo + "text-align");
  401. if (alignMent != null)
  402. {
  403. alignMent = alignMent.ToLower().Replace("end", "right");
  404. if (alignMent.ToLower() == "center" || alignMent.ToLower() == "right")
  405. style += "text-align: " + alignMent + "; ";
  406. }
  407. string lineSpace = (string) paraPropNode.Attribute(Ns.Fo + "line-height");
  408. if (lineSpace != null)
  409. style += "line-height: " + lineSpace + "; ";
  410. string marginTop = (string) paraPropNode.Attribute(Ns.Fo + "margin-top");
  411. if (marginTop != null)
  412. style += "margin-top: " + marginTop + "; ";
  413. string marginBottom = (string) paraPropNode.Attribute(Ns.Fo + "margin-bottom");
  414. if (marginBottom != null)
  415. style += "margin-bottom: " + marginBottom + "; ";
  416. string marginLeft = (string) paraPropNode.Attribute(Ns.Fo + "margin-left");
  417. if (marginLeft != null)
  418. style += "margin-left: " + marginLeft + "; ";
  419. string marginRight = (string) paraPropNode.Attribute(Ns.Fo + "margin-right");
  420. if (marginRight != null)
  421. style += "margin-right: " + marginRight + "; ";
  422. }
  423. XElement textPropNode = styleNode.Element(Ns.Style + "text-properties");
  424. XElement textPropNodeP = null;
  425. if (parentStyleNode != null)
  426. textPropNodeP = parentStyleNode.Element(Ns.Style + "text-properties");
  427. //Check first text properties of parent style
  428. if (textPropNodeP != null)
  429. {
  430. string fontSize = (string) textPropNodeP.Attribute(Ns.Fo + "font-size");
  431. if (fontSize != null)
  432. style += "font-size: " + FontFamilies.PtToPx(fontSize) + "; ";
  433. string italic = (string) textPropNodeP.Attribute(Ns.Fo + "font-style");
  434. if (italic != null)
  435. style += "font-size: italic; ";
  436. string bold = (string) textPropNodeP.Attribute(Ns.Fo + "font-weight");
  437. if (bold != null)
  438. style += "font-weight: bold; ";
  439. string underline = (string) textPropNodeP.Attribute(Ns.Style + "text-underline-style");
  440. if (underline != null)
  441. style += "text-decoration: underline; ";
  442. string fontName = (string) textPropNodeP.Attribute(Ns.Style + "font-name");
  443. if (fontName != null)
  444. style += "font-family: " + FontFamilies.HtmlFont(fontName) + "; ";
  445. string color = (string) textPropNodeP.Attribute(Ns.Fo + "color");
  446. if (color != null)
  447. style += "color: " + color + "; ";
  448. }
  449. //Check now text properties of style, maybe some setting are overwritten or extended
  450. if (textPropNode != null)
  451. {
  452. string fontSize = (string) textPropNode.Attribute(Ns.Fo + "font-size");
  453. if (fontSize != null)
  454. style += "font-size: " + FontFamilies.PtToPx(fontSize) + "; ";
  455. string italic = (string) textPropNode.Attribute(Ns.Fo + "font-style");
  456. if (italic != null)
  457. style += "font-size: italic; ";
  458. string bold = (string) textPropNode.Attribute(Ns.Fo + "font-weight");
  459. if (bold != null)
  460. style += "font-weight: bold; ";
  461. string underline = (string) textPropNode.Attribute(Ns.Style + "text-underline-style");
  462. if (underline != null)
  463. style += "text-decoration: underline; ";
  464. string fontName = (string) textPropNode.Attribute(Ns.Style + "font-name");
  465. if (fontName != null)
  466. style += "font-family: " + FontFamilies.HtmlFont(fontName) + "; ";
  467. string color = (string) textPropNode.Attribute(Ns.Fo + "color");
  468. if (color != null)
  469. style += "color: " + color + "; ";
  470. }
  471. }
  472. }
  473. if (!style.EndsWith("; "))
  474. style = "";
  475. else
  476. style += "\"";
  477. return style;
  478. }
  479. catch (Exception)
  480. {
  481. //unhandled, only a paragraph style wouldn't be displayed correct
  482. //Console.WriteLine("GetHtmlStyleFromGlobalStyles(): {0}", ex.Message);
  483. }
  484. return "";
  485. }
  486. #endregion
  487. #region ITextContainer Member
  488. private ITextCollection _textContent;
  489. /// <summary>
  490. /// All Content objects have a Text container. Which represents
  491. /// his Text this could be SimpleText, FormatedText or mixed.
  492. /// </summary>
  493. /// <value></value>
  494. public ITextCollection TextContent
  495. {
  496. get { return _textContent; }
  497. set
  498. {
  499. if (_textContent != null)
  500. foreach (IText text in _textContent)
  501. text.Node.Remove();
  502. _textContent = value;
  503. if (_textContent != null)
  504. foreach (IText text in _textContent)
  505. Node.Add(text.Node);
  506. }
  507. }
  508. #endregion
  509. #region ICloneable Member
  510. /// <summary>
  511. /// Create a deep clone of this paragraph object.
  512. /// </summary>
  513. /// <remarks>A possible Attached Style wouldn't be cloned!</remarks>
  514. /// <returns>
  515. /// A clone of this object.
  516. /// </returns>
  517. public object Clone()
  518. {
  519. Paragraph pargaphClone = null;
  520. if (Document != null && Node != null)
  521. {
  522. MainContentProcessor mcp = new MainContentProcessor(Document);
  523. pargaphClone = mcp.CreateParagraph(new XElement(Node));
  524. }
  525. return pargaphClone;
  526. }
  527. #endregion
  528. #region IContentContainer Member
  529. private ContentCollection _content;
  530. /// <summary>
  531. /// Gets or sets the content.
  532. /// </summary>
  533. /// <value>The content.</value>
  534. public ContentCollection Content
  535. {
  536. get { return _content; }
  537. set
  538. {
  539. if (_content != null)
  540. foreach (IContent content in _content)
  541. content.Node.Remove();
  542. _content = value;
  543. if (_content != null)
  544. foreach (IContent content in _content)
  545. Node.Add(content.Node);
  546. }
  547. }
  548. #endregion
  549. #region IContent Member
  550. private IStyle _style;
  551. /// <summary>
  552. /// Gets or sets the node.
  553. /// </summary>
  554. /// <value>The node.</value>
  555. public XElement Node { get; set; }
  556. /// <summary>
  557. /// Gets or sets the name of the style.
  558. /// </summary>
  559. /// <value>The name of the style.</value>
  560. public string StyleName
  561. {
  562. get { return (string) Node.Attribute(Ns.Text + "style-name"); }
  563. set { Node.SetAttributeValue(Ns.Text + "style-name", value); }
  564. }
  565. /// <summary>
  566. /// Every object (typeof(IContent)) have to know his document.
  567. /// </summary>
  568. /// <value></value>
  569. public IDocument Document { get; set; }
  570. /// <summary>
  571. /// A Style class wich is referenced with the content object.
  572. /// If no style is available this is null.
  573. /// </summary>
  574. /// <value></value>
  575. public IStyle Style
  576. {
  577. get { return _style; }
  578. set
  579. {
  580. StyleName = value.StyleName;
  581. _style = value;
  582. }
  583. }
  584. /// <summary>
  585. /// Gets or sets the node.
  586. /// </summary>
  587. /// <value>The node.</value>
  588. XNode IContent.Node
  589. {
  590. get { return Node; }
  591. set { Node = (XElement) value; }
  592. }
  593. #endregion
  594. }
  595. }
  596. /*
  597. * $Log: Paragraph.cs,v $
  598. * Revision 1.3 2008/04/29 15:39:46 mt
  599. * new copyright header
  600. *
  601. * Revision 1.2 2007/04/08 16:51:23 larsbehr
  602. * - finished master pages and styles for text documents
  603. * - several bug fixes
  604. *
  605. * Revision 1.1 2007/02/25 08:58:39 larsbehr
  606. * initial checkin, import from Sourceforge.net to OpenOffice.org
  607. *
  608. * Revision 1.3 2006/02/02 21:55:59 larsbm
  609. * - Added Clone object support for many AODL object types
  610. * - New Importer implementation PlainTextImporter and CsvImporter
  611. * - New tests
  612. *
  613. * Revision 1.2 2006/01/29 18:52:14 larsbm
  614. * - Added support for common styles (style templates in OpenOffice)
  615. * - Draw TextBox import and export
  616. * - DrawTextBox html export
  617. *
  618. * Revision 1.1 2006/01/29 11:28:22 larsbm
  619. * - Changes for the new version. 1.2. see next changelog for details
  620. *
  621. * Revision 1.11 2006/01/05 10:31:10 larsbm
  622. * - AODL merged cells
  623. * - AODL toc
  624. * - AODC batch mode, splash screen
  625. *
  626. * Revision 1.10 2005/12/18 18:29:46 larsbm
  627. * - AODC Gui redesign
  628. * - AODC HTML exporter refecatored
  629. * - Full Meta Data Support
  630. * - Increase textprocessing performance
  631. *
  632. * Revision 1.9 2005/12/12 19:39:17 larsbm
  633. * - Added Paragraph Header
  634. * - Added Table Row Header
  635. * - Fixed some bugs
  636. * - better whitespace handling
  637. * - Implmemenation of HTML Exporter
  638. *
  639. * Revision 1.8 2005/11/20 17:31:20 larsbm
  640. * - added suport for XLinks, TabStopStyles
  641. * - First experimental of loading dcuments
  642. * - load and save via importer and exporter interfaces
  643. *
  644. * Revision 1.7 2005/10/23 16:47:48 larsbm
  645. * - Bugfix ListItem throws IStyleInterface not implemented exeption
  646. * - now. build the document after call saveto instead prepare the do at runtime
  647. * - add remove support for IText objects in the paragraph class
  648. *
  649. * Revision 1.6 2005/10/22 10:47:41 larsbm
  650. * - add graphic support
  651. *
  652. * Revision 1.5 2005/10/15 11:40:31 larsbm
  653. * - finished first step for table support
  654. *
  655. * Revision 1.4 2005/10/09 15:52:47 larsbm
  656. * - Changed some design at the paragraph usage
  657. * - add list support
  658. *
  659. * Revision 1.3 2005/10/08 12:31:33 larsbm
  660. * - better usabilty of paragraph handling
  661. * - create paragraphs with text and blank paragraphs with one line of code
  662. *
  663. * Revision 1.2 2005/10/08 08:19:25 larsbm
  664. * - added cvs tags
  665. *
  666. */