using System; using System.Linq; using System.Xml.Linq; namespace Novacode { /// /// All DocX types are derived from DocXElement. /// This class contains properties which every element of a DocX must contain. /// public abstract class DocXElement { /// /// This is the actual Xml that gives this element substance. /// For example, a Paragraphs Xml might look something like the following ///

/// /// Hello World! /// ///

///
public XElement Xml { get; set; } /// /// This is a reference to the DocX object that this element belongs to. /// Every DocX element is connected to a document. /// internal DocX Document { get; set; } /// /// Store both the document and xml so that they can be accessed by derived types. /// /// The document that this element belongs to. /// The Xml that gives this element substance public DocXElement(DocX document, XElement xml) { this.Document = document; this.Xml = xml; } } /// /// This class provides functions for inserting new DocXElements before or after the current DocXElement. /// Only certain DocXElements can support these functions without creating invalid documents, at the moment these are Paragraphs and Table. /// public abstract class InsertBeforeOrAfter : DocXElement { public InsertBeforeOrAfter(DocX document, XElement xml) : base(document, xml) { } public virtual void InsertPageBreakBeforeSelf() { XElement p = new XElement ( XName.Get("p", DocX.w.NamespaceName), new XElement ( XName.Get("r", DocX.w.NamespaceName), new XElement ( XName.Get("br", DocX.w.NamespaceName), new XAttribute(XName.Get("type", DocX.w.NamespaceName), "page") ) ) ); Xml.AddBeforeSelf(p); } public virtual void InsertPageBreakAfterSelf() { XElement p = new XElement ( XName.Get("p", DocX.w.NamespaceName), new XElement ( XName.Get("r", DocX.w.NamespaceName), new XElement ( XName.Get("br", DocX.w.NamespaceName), new XAttribute(XName.Get("type", DocX.w.NamespaceName), "page") ) ) ); Xml.AddAfterSelf(p); } public virtual Paragraph InsertParagraphBeforeSelf(Paragraph p) { Xml.AddBeforeSelf(p.Xml); XElement newlyInserted = Xml.ElementsBeforeSelf().First(); p.Xml = newlyInserted; return p; } public virtual Paragraph InsertParagraphAfterSelf(Paragraph p) { Xml.AddAfterSelf(p.Xml); XElement newlyInserted = Xml.ElementsAfterSelf().First(); //Dmitchern if (this as Paragraph != null) { return new Paragraph(Document, newlyInserted, (this as Paragraph).endIndex); } else { p.Xml = newlyInserted; //IMPORTANT: I think we have return new paragraph in any case, but I dont know what to put as startIndex parameter into Paragraph constructor return p; } } public virtual Paragraph InsertParagraphBeforeSelf(string text) { return InsertParagraphBeforeSelf(text, false, new Formatting()); } public virtual Paragraph InsertParagraphAfterSelf(string text) { return InsertParagraphAfterSelf(text, false, new Formatting()); } public virtual Paragraph InsertParagraphBeforeSelf(string text, bool trackChanges) { return InsertParagraphBeforeSelf(text, trackChanges, new Formatting()); } public virtual Paragraph InsertParagraphAfterSelf(string text, bool trackChanges) { return InsertParagraphAfterSelf(text, trackChanges, new Formatting()); } public virtual Paragraph InsertParagraphBeforeSelf(string text, bool trackChanges, Formatting formatting) { XElement newParagraph = new XElement ( XName.Get("p", DocX.w.NamespaceName), new XElement(XName.Get("pPr", DocX.w.NamespaceName)), HelperFunctions.FormatInput(text, formatting.Xml) ); if (trackChanges) newParagraph = Paragraph.CreateEdit(EditType.ins, DateTime.Now, newParagraph); Xml.AddBeforeSelf(newParagraph); XElement newlyInserted = Xml.ElementsBeforeSelf().Last(); Paragraph p = new Paragraph(Document, newlyInserted, -1); return p; } public virtual Paragraph InsertParagraphAfterSelf(string text, bool trackChanges, Formatting formatting) { XElement newParagraph = new XElement ( XName.Get("p", DocX.w.NamespaceName), new XElement(XName.Get("pPr", DocX.w.NamespaceName)), HelperFunctions.FormatInput(text, formatting.Xml) ); if (trackChanges) newParagraph = Paragraph.CreateEdit(EditType.ins, DateTime.Now, newParagraph); Xml.AddAfterSelf(newParagraph); XElement newlyInserted = Xml.ElementsAfterSelf().First(); Paragraph p = new Paragraph(Document, newlyInserted, -1); return p; } public virtual Table InsertTableAfterSelf(int rowCount, int columnCount) { XElement newTable = HelperFunctions.CreateTable(rowCount, columnCount); Xml.AddAfterSelf(newTable); XElement newlyInserted = Xml.ElementsAfterSelf().First(); return new Table(Document, newlyInserted); } public virtual Table InsertTableAfterSelf(Table t) { Xml.AddAfterSelf(t.Xml); XElement newlyInserted = Xml.ElementsAfterSelf().First(); //Dmitchern return new Table(Document, newlyInserted); //return new table, dont affect parameter table //t.Xml = newlyInserted; //return t; } public virtual Table InsertTableBeforeSelf(int rowCount, int columnCount) { XElement newTable = HelperFunctions.CreateTable(rowCount, columnCount); Xml.AddBeforeSelf(newTable); XElement newlyInserted = Xml.ElementsBeforeSelf().Last(); return new Table(Document, newlyInserted); } public virtual Table InsertTableBeforeSelf(Table t) { Xml.AddBeforeSelf(t.Xml); XElement newlyInserted = Xml.ElementsBeforeSelf().Last(); //Dmitchern return new Table(Document, newlyInserted); //return new table, dont affect parameter table //t.Xml = newlyInserted; //return t; } } }