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;
}
}
}