Paragraphs { get; }
8 | }
9 | }
--------------------------------------------------------------------------------
/src/DocXCore/Image.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO.Packaging;
3 | using System.IO;
4 |
5 | namespace Novacode
6 | {
7 | ///
8 | /// Represents an Image embedded in a document.
9 | ///
10 | public class Image
11 | {
12 | ///
13 | /// A unique id which identifies this Image.
14 | ///
15 | private string id;
16 | private DocX document;
17 | internal PackageRelationship pr;
18 |
19 | public Stream GetStream(FileMode mode, FileAccess access)
20 | {
21 | string temp = pr.SourceUri.OriginalString;
22 | string start = temp.Remove(temp.LastIndexOf('/'));
23 | string end = pr.TargetUri.OriginalString;
24 | string full = end.Contains(start) ? end : start + "/" + end;
25 |
26 | return (new PackagePartStream(document.package.GetPart(new Uri(full, UriKind.Relative)).GetStream(mode, access)));
27 | }
28 |
29 | ///
30 | /// Returns the id of this Image.
31 | ///
32 | public string Id
33 | {
34 | get {return id;}
35 | }
36 |
37 | internal Image(DocX document, PackageRelationship pr)
38 | {
39 | this.document = document;
40 | this.pr = pr;
41 | this.id = pr.Id;
42 | }
43 |
44 | ///
45 | /// Add an image to a document, create a custom view of that image (picture) and then insert it into a Paragraph using append.
46 | ///
47 | ///
48 | ///
49 | /// Add an image to a document, create a custom view of that image (picture) and then insert it into a Paragraph using append.
50 | ///
51 | /// using (DocX document = DocX.Create("Test.docx"))
52 | /// {
53 | /// // Add an image to the document.
54 | /// Image i = document.AddImage(@"Image.jpg");
55 | ///
56 | /// // Create a picture i.e. (A custom view of an image)
57 | /// Picture p = i.CreatePicture();
58 | /// p.FlipHorizontal = true;
59 | /// p.Rotation = 10;
60 | ///
61 | /// // Create a new Paragraph.
62 | /// Paragraph par = document.InsertParagraph();
63 | ///
64 | /// // Append content to the Paragraph.
65 | /// par.Append("Here is a cool picture")
66 | /// .AppendPicture(p)
67 | /// .Append(" don't you think so?");
68 | ///
69 | /// // Save all changes made to this document.
70 | /// document.Save();
71 | /// }
72 | ///
73 | ///
74 | public Picture CreatePicture()
75 | {
76 | return Paragraph.CreatePicture(document, id, string.Empty, string.Empty);
77 | }
78 | public Picture CreatePicture(int height, int width) {
79 | Picture picture = Paragraph.CreatePicture(document, id, string.Empty, string.Empty);
80 | picture.Height = height;
81 | picture.Width = width;
82 | return picture;
83 | }
84 |
85 | ///
86 | /// Returns the name of the image file.
87 | ///
88 | public string FileName
89 | {
90 | get
91 | {
92 | return Path.GetFileName(this.pr.TargetUri.ToString());
93 | }
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/DocXCore/License/License.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Microsoft Public License (Ms-PL)
This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software.
1. Definitions
The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law.
A "contribution" is the original software, or any additions or changes to the software.
A "contributor" is any person that distributes its contribution under this license.
"Licensed patents" are a contributor's patent claims that read directly on its contribution.
2. Grant of Rights
(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
3. Conditions and Limitations
(A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
(B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
(C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software.
(D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
(E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/DocXCore/List.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Xml.Linq;
5 |
6 | namespace Novacode
7 | {
8 | ///
9 | /// Represents a List in a document.
10 | ///
11 | public class List : InsertBeforeOrAfter
12 | {
13 | ///
14 | /// This is a list of paragraphs that will be added to the document
15 | /// when the list is inserted into the document.
16 | /// The paragraph needs a numPr defined to be in this items collection.
17 | ///
18 | public List Items { get; private set; }
19 | ///
20 | /// The numId used to reference the list settings in the numbering.xml
21 | ///
22 | public int NumId { get; private set; }
23 | ///
24 | /// The ListItemType (bullet or numbered) of the list.
25 | ///
26 | public ListItemType? ListType { get; private set; }
27 |
28 | internal List(DocX document, XElement xml)
29 | : base(document, xml)
30 | {
31 | Items = new List();
32 | ListType = null;
33 | }
34 |
35 | ///
36 | /// Adds an item to the list.
37 | ///
38 | ///
39 | ///
40 | /// Throws an InvalidOperationException if the item cannot be added to the list.
41 | ///
42 | public void AddItem(Paragraph paragraph)
43 | {
44 | if (paragraph.IsListItem)
45 | {
46 | var numIdNode = paragraph.Xml.Descendants().First(s => s.Name.LocalName == "numId");
47 | var numId = Int32.Parse(numIdNode.Attribute(DocX.w + "val").Value);
48 |
49 | if (CanAddListItem(paragraph))
50 | {
51 | NumId = numId;
52 | Items.Add(paragraph);
53 | }
54 | else
55 | throw new InvalidOperationException("New list items can only be added to this list if they are have the same numId.");
56 | }
57 | }
58 |
59 | public void AddItemWithStartValue(Paragraph paragraph, int start)
60 | {
61 | //TODO: Update the numbering
62 | UpdateNumberingForLevelStartNumber(int.Parse(paragraph.IndentLevel.ToString()), start);
63 | if (ContainsLevel(start))
64 | throw new InvalidOperationException("Cannot add a paragraph with a start value if another element already exists in this list with that level.");
65 | AddItem(paragraph);
66 | }
67 |
68 | private void UpdateNumberingForLevelStartNumber(int iLevel, int start)
69 | {
70 | var abstractNum = GetAbstractNum(NumId);
71 | var level = abstractNum.Descendants().First(el => el.Name.LocalName == "lvl" && el.GetAttribute(DocX.w + "ilvl") == iLevel.ToString());
72 | level.Descendants().First(el => el.Name.LocalName == "start").SetAttributeValue(DocX.w + "val", start);
73 | }
74 |
75 | ///
76 | /// Determine if it is able to add the item to the list
77 | ///
78 | ///
79 | ///
80 | /// Return true if AddItem(...) will succeed with the given paragraph.
81 | ///
82 | public bool CanAddListItem(Paragraph paragraph)
83 | {
84 | if (paragraph.IsListItem)
85 | {
86 | //var lvlNode = paragraph.Xml.Descendants().First(s => s.Name.LocalName == "ilvl");
87 | var numIdNode = paragraph.Xml.Descendants().First(s => s.Name.LocalName == "numId");
88 | var numId = Int32.Parse(numIdNode.Attribute(DocX.w + "val").Value);
89 |
90 | //Level = Int32.Parse(lvlNode.Attribute(DocX.w + "val").Value);
91 | if (NumId == 0 || (numId == NumId && numId > 0))
92 | {
93 | return true;
94 | }
95 | }
96 | return false;
97 | }
98 |
99 | public bool ContainsLevel(int ilvl)
100 | {
101 | return Items.Any(i => i.ParagraphNumberProperties.Descendants().First(el => el.Name.LocalName == "ilvl").Value == ilvl.ToString());
102 | }
103 |
104 | internal void CreateNewNumberingNumId(int level = 0, ListItemType listType = ListItemType.Numbered, int? startNumber = null, bool continueNumbering = false)
105 | {
106 | ValidateDocXNumberingPartExists();
107 | if (Document.numbering.Root == null)
108 | {
109 | throw new InvalidOperationException("Numbering section did not instantiate properly.");
110 | }
111 |
112 | ListType = listType;
113 |
114 | var numId = GetMaxNumId() + 1;
115 | var abstractNumId = GetMaxAbstractNumId() + 1;
116 |
117 | XDocument listTemplate;
118 | switch (listType)
119 | {
120 | case ListItemType.Bulleted:
121 | listTemplate = HelperFunctions.DecompressXMLResource("Novacode.Resources.numbering.default_bullet_abstract.xml.gz");
122 | break;
123 | case ListItemType.Numbered:
124 | listTemplate = HelperFunctions.DecompressXMLResource("Novacode.Resources.numbering.default_decimal_abstract.xml.gz");
125 | break;
126 | default:
127 | throw new InvalidOperationException(string.Format("Unable to deal with ListItemType: {0}.", listType.ToString()));
128 | }
129 |
130 | var abstractNumTemplate = listTemplate.Descendants().Single(d => d.Name.LocalName == "abstractNum");
131 | abstractNumTemplate.SetAttributeValue(DocX.w + "abstractNumId", abstractNumId);
132 |
133 | //Fixing an issue where numbering would continue from previous numbered lists. Setting startOverride assures that a numbered list starts on the provided number.
134 | //The override needs only be on level 0 as this will cascade to the rest of the list.
135 | var abstractNumXml = GetAbstractNumXml(abstractNumId, numId, startNumber, continueNumbering);
136 |
137 | var abstractNumNode = Document.numbering.Root.Descendants().LastOrDefault(xElement => xElement.Name.LocalName == "abstractNum");
138 | var numXml = Document.numbering.Root.Descendants().LastOrDefault(xElement => xElement.Name.LocalName == "num");
139 |
140 | if (abstractNumNode == null || numXml == null)
141 | {
142 | Document.numbering.Root.Add(abstractNumTemplate);
143 | Document.numbering.Root.Add(abstractNumXml);
144 | }
145 | else
146 | {
147 | abstractNumNode.AddAfterSelf(abstractNumTemplate);
148 | numXml.AddAfterSelf(
149 | abstractNumXml
150 | );
151 | }
152 |
153 | NumId = numId;
154 | }
155 |
156 | private XElement GetAbstractNumXml(int abstractNumId, int numId, int? startNumber, bool continueNumbering)
157 | {
158 | //Fixing an issue where numbering would continue from previous numbered lists. Setting startOverride assures that a numbered list starts on the provided number.
159 | //The override needs only be on level 0 as this will cascade to the rest of the list.
160 | var startOverride = new XElement(XName.Get("startOverride", DocX.w.NamespaceName), new XAttribute(DocX.w + "val", startNumber ?? 1));
161 | var lvlOverride = new XElement(XName.Get("lvlOverride", DocX.w.NamespaceName), new XAttribute(DocX.w + "ilvl", 0), startOverride);
162 | var abstractNumIdElement = new XElement(XName.Get("abstractNumId", DocX.w.NamespaceName), new XAttribute(DocX.w + "val", abstractNumId));
163 | return continueNumbering
164 | ? new XElement(XName.Get("num", DocX.w.NamespaceName), new XAttribute(DocX.w + "numId", numId), abstractNumIdElement)
165 | : new XElement(XName.Get("num", DocX.w.NamespaceName), new XAttribute(DocX.w + "numId", numId), abstractNumIdElement, lvlOverride);
166 | }
167 |
168 | ///
169 | /// Method to determine the last numId for a list element.
170 | /// Also useful for determining the next numId to use for inserting a new list element into the document.
171 | ///
172 | ///
173 | /// 0 if there are no elements in the list already.
174 | /// Increment the return for the next valid value of a new list element.
175 | ///
176 | private int GetMaxNumId()
177 | {
178 | const int defaultValue = 0;
179 | if (Document.numbering == null)
180 | return defaultValue;
181 |
182 | var numlist = Document.numbering.Descendants().Where(d => d.Name.LocalName == "num").ToList();
183 | if (numlist.Any())
184 | return numlist.Attributes(DocX.w + "numId").Max(e => int.Parse(e.Value));
185 | return defaultValue;
186 | }
187 |
188 | ///
189 | /// Method to determine the last abstractNumId for a list element.
190 | /// Also useful for determining the next abstractNumId to use for inserting a new list element into the document.
191 | ///
192 | ///
193 | /// -1 if there are no elements in the list already.
194 | /// Increment the return for the next valid value of a new list element.
195 | ///
196 | private int GetMaxAbstractNumId()
197 | {
198 | const int defaultValue = -1;
199 |
200 | if (Document.numbering == null)
201 | return defaultValue;
202 |
203 | var numlist = Document.numbering.Descendants().Where(d => d.Name.LocalName == "abstractNum").ToList();
204 | if (numlist.Any())
205 | {
206 | var maxAbstractNumId = numlist.Attributes(DocX.w + "abstractNumId").Max(e => int.Parse(e.Value));
207 | return maxAbstractNumId;
208 | }
209 | return defaultValue;
210 | }
211 |
212 | ///
213 | /// Get the abstractNum definition for the given numId
214 | ///
215 | /// The numId on the pPr element
216 | /// XElement representing the requested abstractNum
217 | internal XElement GetAbstractNum(int numId)
218 | {
219 | var num = Document.numbering.Descendants().First(d => d.Name.LocalName == "num" && d.GetAttribute(DocX.w + "numId").Equals(numId.ToString()));
220 | var abstractNumId = num.Descendants().First(d => d.Name.LocalName == "abstractNumId");
221 | return Document.numbering.Descendants()
222 | .First(d => d.Name.LocalName == "abstractNum" && d.GetAttribute(DocX.w + "abstractNumId")
223 | .Equals(abstractNumId.GetAttribute(DocX.w + "val")));
224 | }
225 |
226 | private void ValidateDocXNumberingPartExists()
227 | {
228 | var numberingUri = new Uri("/word/numbering.xml", UriKind.Relative);
229 |
230 | // If the internal document contains no /word/numbering.xml create one.
231 | if (!Document.package.PartExists(numberingUri))
232 | {
233 | Document.numbering = HelperFunctions.AddDefaultNumberingXml(Document.package);
234 | Document.numberingPart = Document.package.GetPart(numberingUri);
235 | }
236 | }
237 | }
238 | }
239 |
--------------------------------------------------------------------------------
/src/DocXCore/NETCorePort/Color.cs:
--------------------------------------------------------------------------------
1 | namespace Novacode.NETCorePort
2 | {
3 | public class DefinedColors
4 | {
5 | public static string White => "ffffff";
6 | public static string Transparent => "transparent";
7 | public static string Black => "000000";
8 | public static string Empty => null;
9 | }
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/src/DocXCore/NETCorePort/DescriptionAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | #if NETSTANDARD1_6
4 | namespace Novacode.NETCorePort
5 | {
6 |
7 | public class DescriptionAttribute:Attribute
8 | {
9 | public DescriptionAttribute(string description)
10 | {
11 | Description = description;
12 | }
13 |
14 | public string Description { get; }
15 | }
16 | }
17 | #endif
18 |
--------------------------------------------------------------------------------
/src/DocXCore/NETCorePort/StringExtensions.cs:
--------------------------------------------------------------------------------
1 | namespace Novacode.NETCorePort
2 | {
3 | public static class StringExtensions
4 | {
5 | public static bool HasValue(this string val)
6 | {
7 | return !string.IsNullOrEmpty(val);
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/DocXCore/PackagePartStream.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 |
3 | namespace Novacode
4 | {
5 | ///
6 | /// OpenXML Isolated Storage access is not thread safe.
7 | /// Use app domain wide lock for writing.
8 | ///
9 | public class PackagePartStream : Stream
10 | {
11 | private static readonly object lockObject = new object();
12 |
13 | private readonly Stream stream;
14 |
15 | public PackagePartStream(Stream stream)
16 | {
17 | this.stream = stream;
18 | }
19 |
20 | public override bool CanRead
21 | {
22 | get { return this.stream.CanRead; }
23 | }
24 |
25 | public override bool CanSeek
26 | {
27 | get { return this.stream.CanSeek; }
28 | }
29 |
30 | public override bool CanWrite
31 | {
32 | get { return this.stream.CanWrite; }
33 | }
34 |
35 | public override long Length
36 | {
37 | get { return this.stream.Length; }
38 | }
39 |
40 | public override long Position
41 | {
42 | get { return this.stream.Position; }
43 | set { this.stream.Position = value; }
44 | }
45 |
46 | public override long Seek(long offset, SeekOrigin origin)
47 | {
48 | return this.stream.Seek(offset, origin);
49 | }
50 |
51 | public override void SetLength(long value)
52 | {
53 | this.stream.SetLength(value);
54 | }
55 |
56 | public override int Read(byte[] buffer, int offset, int count)
57 | {
58 | return this.stream.Read(buffer, offset, count);
59 | }
60 |
61 | public override void Write(byte[] buffer, int offset, int count)
62 | {
63 | lock (lockObject)
64 | {
65 | this.stream.Write(buffer, offset, count);
66 | }
67 | }
68 |
69 | public override void Flush()
70 | {
71 | lock (lockObject)
72 | {
73 | this.stream.Flush();
74 | }
75 | }
76 |
77 | #if NETSTANDARD1_6
78 | public void Close()
79 | {
80 | this.stream.Dispose();
81 | }
82 | #else
83 | public override void Close()
84 | {
85 | this.stream.Close();
86 | }
87 | #endif
88 | protected override void Dispose(bool disposing)
89 | {
90 | this.stream.Flush();
91 | this.stream.Dispose();
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/DocXCore/PageLayout.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Xml.Linq;
3 |
4 | namespace Novacode
5 | {
6 | public class PageLayout: DocXElement
7 | {
8 | internal PageLayout(DocX document, XElement xml):base(document, xml)
9 | {
10 |
11 | }
12 |
13 |
14 | public Orientation Orientation
15 | {
16 | get
17 | {
18 | /*
19 | * Get the pgSz (page size) element for this Section,
20 | * null will be return if no such element exists.
21 | */
22 | XElement pgSz = Xml.Element(XName.Get("pgSz", DocX.w.NamespaceName));
23 |
24 | if (pgSz == null)
25 | return Orientation.Portrait;
26 |
27 | // Get the attribute of the pgSz element.
28 | XAttribute val = pgSz.Attribute(XName.Get("orient", DocX.w.NamespaceName));
29 |
30 | // If val is null, this cell contains no information.
31 | if (val == null)
32 | return Orientation.Portrait;
33 |
34 | if (val.Value.Equals("Landscape", StringComparison.CurrentCultureIgnoreCase))
35 | return Orientation.Landscape;
36 | else
37 | return Orientation.Portrait;
38 | }
39 |
40 | set
41 | {
42 | // Check if already correct value.
43 | if (Orientation == value)
44 | return;
45 |
46 | /*
47 | * Get the pgSz (page size) element for this Section,
48 | * null will be return if no such element exists.
49 | */
50 | XElement pgSz = Xml.Element(XName.Get("pgSz", DocX.w.NamespaceName));
51 |
52 | if (pgSz == null)
53 | {
54 | Xml.SetElementValue(XName.Get("pgSz", DocX.w.NamespaceName), string.Empty);
55 | pgSz = Xml.Element(XName.Get("pgSz", DocX.w.NamespaceName));
56 | }
57 |
58 | pgSz.SetAttributeValue(XName.Get("orient", DocX.w.NamespaceName), value.ToString().ToLower());
59 |
60 | if(value == Novacode.Orientation.Landscape)
61 | {
62 | pgSz.SetAttributeValue(XName.Get("w", DocX.w.NamespaceName), "16838");
63 | pgSz.SetAttributeValue(XName.Get("h", DocX.w.NamespaceName), "11906");
64 | }
65 |
66 | else if (value == Novacode.Orientation.Portrait)
67 | {
68 | pgSz.SetAttributeValue(XName.Get("w", DocX.w.NamespaceName), "11906");
69 | pgSz.SetAttributeValue(XName.Get("h", DocX.w.NamespaceName), "16838");
70 | }
71 | }
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/DocXCore/Picture.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Xml.Linq;
4 | using System.IO.Packaging;
5 |
6 | namespace Novacode
7 | {
8 | ///
9 | /// Represents a Picture in this document, a Picture is a customized view of an Image.
10 | ///
11 | public class Picture: DocXElement
12 | {
13 | private const int EmusInPixel = 9525;
14 |
15 | internal Dictionary picture_rels;
16 |
17 | internal Image img;
18 | private string id;
19 | private string name;
20 | private string descr;
21 | private int cx, cy;
22 | //private string fileName;
23 | private uint rotation;
24 | private bool hFlip, vFlip;
25 | private object pictureShape;
26 | private XElement xfrm;
27 | private XElement prstGeom;
28 |
29 | ///
30 | /// Remove this Picture from this document.
31 | ///
32 | public void Remove()
33 | {
34 | Xml.Remove();
35 | }
36 |
37 | ///
38 | /// Wraps an XElement as an Image
39 | ///
40 | ///
41 | /// The XElement i to wrap
42 | ///
43 | internal Picture(DocX document, XElement i, Image img):base(document, i)
44 | {
45 | picture_rels = new Dictionary();
46 |
47 | this.img = img;
48 |
49 | this.id =
50 | (
51 | from e in Xml.Descendants()
52 | where e.Name.LocalName.Equals("blip")
53 | select e.Attribute(XName.Get("embed", "http://schemas.openxmlformats.org/officeDocument/2006/relationships")).Value
54 | ).SingleOrDefault();
55 |
56 | if (this.id == null)
57 | {
58 | this.id =
59 | (
60 | from e in Xml.Descendants()
61 | where e.Name.LocalName.Equals("imagedata")
62 | select e.Attribute(XName.Get("id", "http://schemas.openxmlformats.org/officeDocument/2006/relationships")).Value
63 | ).SingleOrDefault();
64 | }
65 |
66 | this.name =
67 | (
68 | from e in Xml.Descendants()
69 | let a = e.Attribute(XName.Get("name"))
70 | where (a != null)
71 | select a.Value
72 | ).FirstOrDefault();
73 |
74 | if (this.name == null)
75 | {
76 | this.name =
77 | (
78 | from e in Xml.Descendants()
79 | let a = e.Attribute(XName.Get("title"))
80 | where (a != null)
81 | select a.Value
82 | ).FirstOrDefault();
83 | }
84 |
85 | this.descr =
86 | (
87 | from e in Xml.Descendants()
88 | let a = e.Attribute(XName.Get("descr"))
89 | where (a != null)
90 | select a.Value
91 | ).FirstOrDefault();
92 |
93 | this.cx =
94 | (
95 | from e in Xml.Descendants()
96 | let a = e.Attribute(XName.Get("cx"))
97 | where (a != null)
98 | select int.Parse(a.Value)
99 | ).FirstOrDefault();
100 |
101 | if (this.cx == 0)
102 | {
103 | XAttribute style =
104 | (
105 | from e in Xml.Descendants()
106 | let a = e.Attribute(XName.Get("style"))
107 | where (a != null)
108 | select a
109 | ).FirstOrDefault();
110 |
111 | string fromWidth = style.Value.Substring(style.Value.IndexOf("width:") + 6);
112 | var widthInt = ((double.Parse((fromWidth.Substring(0, fromWidth.IndexOf("pt"))).Replace(".", ","))) / 72.0) * 914400;
113 | cx = System.Convert.ToInt32(widthInt);
114 | }
115 |
116 | this.cy =
117 | (
118 | from e in Xml.Descendants()
119 | let a = e.Attribute(XName.Get("cy"))
120 | where (a != null)
121 | select int.Parse(a.Value)
122 | ).FirstOrDefault();
123 |
124 | if (this.cy == 0)
125 | {
126 | XAttribute style =
127 | (
128 | from e in Xml.Descendants()
129 | let a = e.Attribute(XName.Get("style"))
130 | where (a != null)
131 | select a
132 | ).FirstOrDefault();
133 |
134 | string fromHeight = style.Value.Substring(style.Value.IndexOf("height:") + 7);
135 | var heightInt = ((double.Parse((fromHeight.Substring(0, fromHeight.IndexOf("pt"))).Replace(".", ","))) / 72.0) * 914400;
136 | cy = System.Convert.ToInt32(heightInt);
137 | }
138 |
139 | this.xfrm =
140 | (
141 | from d in Xml.Descendants()
142 | where d.Name.LocalName.Equals("xfrm")
143 | select d
144 | ).SingleOrDefault();
145 |
146 | this.prstGeom =
147 | (
148 | from d in Xml.Descendants()
149 | where d.Name.LocalName.Equals("prstGeom")
150 | select d
151 | ).SingleOrDefault();
152 |
153 | if (xfrm != null)
154 | this.rotation = xfrm.Attribute(XName.Get("rot")) == null ? 0 : uint.Parse(xfrm.Attribute(XName.Get("rot")).Value);
155 | }
156 |
157 | private void SetPictureShape(object shape)
158 | {
159 | this.pictureShape = shape;
160 |
161 | XAttribute prst = prstGeom.Attribute(XName.Get("prst"));
162 | if (prst == null)
163 | prstGeom.Add(new XAttribute(XName.Get("prst"), "rectangle"));
164 |
165 | prstGeom.Attribute(XName.Get("prst")).Value = shape.ToString();
166 | }
167 |
168 | ///
169 | /// Set the shape of this Picture to one in the BasicShapes enumeration.
170 | ///
171 | /// A shape from the BasicShapes enumeration.
172 | public void SetPictureShape(BasicShapes shape)
173 | {
174 | SetPictureShape((object)shape);
175 | }
176 |
177 | ///
178 | /// Set the shape of this Picture to one in the RectangleShapes enumeration.
179 | ///
180 | /// A shape from the RectangleShapes enumeration.
181 | public void SetPictureShape(RectangleShapes shape)
182 | {
183 | SetPictureShape((object)shape);
184 | }
185 |
186 | ///
187 | /// Set the shape of this Picture to one in the BlockArrowShapes enumeration.
188 | ///
189 | /// A shape from the BlockArrowShapes enumeration.
190 | public void SetPictureShape(BlockArrowShapes shape)
191 | {
192 | SetPictureShape((object)shape);
193 | }
194 |
195 | ///
196 | /// Set the shape of this Picture to one in the EquationShapes enumeration.
197 | ///
198 | /// A shape from the EquationShapes enumeration.
199 | public void SetPictureShape(EquationShapes shape)
200 | {
201 | SetPictureShape((object)shape);
202 | }
203 |
204 | ///
205 | /// Set the shape of this Picture to one in the FlowchartShapes enumeration.
206 | ///
207 | /// A shape from the FlowchartShapes enumeration.
208 | public void SetPictureShape(FlowchartShapes shape)
209 | {
210 | SetPictureShape((object)shape);
211 | }
212 |
213 | ///
214 | /// Set the shape of this Picture to one in the StarAndBannerShapes enumeration.
215 | ///
216 | /// A shape from the StarAndBannerShapes enumeration.
217 | public void SetPictureShape(StarAndBannerShapes shape)
218 | {
219 | SetPictureShape((object)shape);
220 | }
221 |
222 | ///
223 | /// Set the shape of this Picture to one in the CalloutShapes enumeration.
224 | ///
225 | /// A shape from the CalloutShapes enumeration.
226 | public void SetPictureShape(CalloutShapes shape)
227 | {
228 | SetPictureShape((object)shape);
229 | }
230 |
231 | ///
232 | /// A unique id that identifies an Image embedded in this document.
233 | ///
234 | public string Id
235 | {
236 | get { return id; }
237 | }
238 |
239 | ///
240 | /// Flip this Picture Horizontally.
241 | ///
242 | public bool FlipHorizontal
243 | {
244 | get { return hFlip; }
245 |
246 | set
247 | {
248 | hFlip = value;
249 |
250 | XAttribute flipH = xfrm.Attribute(XName.Get("flipH"));
251 | if (flipH == null)
252 | xfrm.Add(new XAttribute(XName.Get("flipH"), "0"));
253 |
254 | xfrm.Attribute(XName.Get("flipH")).Value = hFlip ? "1" : "0";
255 | }
256 | }
257 |
258 | ///
259 | /// Flip this Picture Vertically.
260 | ///
261 | public bool FlipVertical
262 | {
263 | get { return vFlip; }
264 |
265 | set
266 | {
267 | vFlip = value;
268 |
269 | XAttribute flipV = xfrm.Attribute(XName.Get("flipV"));
270 | if (flipV == null)
271 | xfrm.Add(new XAttribute(XName.Get("flipV"), "0"));
272 |
273 | xfrm.Attribute(XName.Get("flipV")).Value = vFlip ? "1" : "0";
274 | }
275 | }
276 |
277 | ///
278 | /// The rotation in degrees of this image, actual value = value % 360
279 | ///
280 | public uint Rotation
281 | {
282 | get { return rotation / 60000; }
283 |
284 | set
285 | {
286 | rotation = (value % 360) * 60000;
287 | XElement xfrm =
288 | (from d in Xml.Descendants()
289 | where d.Name.LocalName.Equals("xfrm")
290 | select d).Single();
291 |
292 | XAttribute rot = xfrm.Attribute(XName.Get("rot"));
293 | if(rot == null)
294 | xfrm.Add(new XAttribute(XName.Get("rot"), 0));
295 |
296 | xfrm.Attribute(XName.Get("rot")).Value = rotation.ToString();
297 | }
298 | }
299 |
300 | ///
301 | /// Gets or sets the name of this Image.
302 | ///
303 | public string Name
304 | {
305 | get { return name; }
306 |
307 | set
308 | {
309 | name = value;
310 |
311 | foreach (XAttribute a in Xml.Descendants().Attributes(XName.Get("name")))
312 | a.Value = name;
313 | }
314 | }
315 |
316 | ///
317 | /// Gets or sets the description for this Image.
318 | ///
319 | public string Description
320 | {
321 | get { return descr; }
322 |
323 | set
324 | {
325 | descr = value;
326 |
327 | foreach (XAttribute a in Xml.Descendants().Attributes(XName.Get("descr")))
328 | a.Value = descr;
329 | }
330 | }
331 |
332 | ///
333 | /// Returns the name of the image file for the picture.
334 | ///
335 | public string FileName
336 | {
337 | get
338 | {
339 | return img.FileName;
340 | }
341 | }
342 |
343 | ///
344 | /// Get or sets the Width of this Image.
345 | ///
346 | public int Width
347 | {
348 | get { return cx / EmusInPixel; }
349 |
350 | set
351 | {
352 | cx = value * EmusInPixel;
353 |
354 | foreach (XAttribute a in Xml.Descendants().Attributes(XName.Get("cx")))
355 | a.Value = (cx).ToString();
356 | }
357 | }
358 |
359 | ///
360 | /// Get or sets the height of this Image.
361 | ///
362 | public int Height
363 | {
364 | get { return cy / EmusInPixel; }
365 |
366 | set
367 | {
368 | cy = value * EmusInPixel;
369 |
370 | foreach (XAttribute a in Xml.Descendants().Attributes(XName.Get("cy")))
371 | a.Value = (cy).ToString();
372 | }
373 | }
374 |
375 | //public void Delete()
376 | //{
377 | // // Remove xml
378 | // i.Remove();
379 |
380 | // // Rebuild the image collection for this paragraph
381 | // // Requires that every Image have a link to its paragraph
382 |
383 | //}
384 | }
385 | }
386 |
--------------------------------------------------------------------------------
/src/DocXCore/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Docx")]
9 | [assembly: AssemblyDescription("A fork of the DocX Project for .NET Core")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("DocX")]
12 | [assembly: AssemblyProduct("Docx")]
13 | [assembly: AssemblyCopyright("DocX @ 2016")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 | [assembly: InternalsVisibleTo("DocX.UnitTest")]
17 | // Allow the UnitTests to get at internal stuff.
18 | [assembly: InternalsVisibleTo("UnitTests")]
19 |
20 | // Setting ComVisible to false makes the types in this assembly not visible
21 | // to COM components. If you need to access a type in this assembly from
22 | // COM, set the ComVisible attribute to true on that type.
23 | [assembly: ComVisible(false)]
24 |
25 | // The following GUID is for the ID of the typelib if this project is exposed to COM
26 | [assembly: Guid("16123f21-f3d1-47bb-ae9a-eb7c82c0f3c8")]
27 |
28 | // Version information for an assembly consists of the following four values:
29 | //
30 | // Major Version
31 | // Minor Version
32 | // Build Number
33 | // Revision
34 | //
35 | // You can specify all the values or you can default the Build and Revision Numbers
36 | // by using the '*' as shown below:
37 | // [assembly: AssemblyVersion("1.0.*")]
38 | [assembly: AssemblyVersion("1.0.0.23")]
39 | [assembly: AssemblyFileVersion("1.0.0.23")]
--------------------------------------------------------------------------------
/src/DocXCore/Resources/default_styles.xml.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocXCore/Resources/default_styles.xml.gz
--------------------------------------------------------------------------------
/src/DocXCore/Resources/numbering.default_bullet_abstract.xml.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocXCore/Resources/numbering.default_bullet_abstract.xml.gz
--------------------------------------------------------------------------------
/src/DocXCore/Resources/numbering.default_decimal_abstract.xml.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocXCore/Resources/numbering.default_decimal_abstract.xml.gz
--------------------------------------------------------------------------------
/src/DocXCore/Resources/numbering.xml.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocXCore/Resources/numbering.xml.gz
--------------------------------------------------------------------------------
/src/DocXCore/Resources/styles.xml.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jetro223/DocXNETCore/576735b8bf61a58096b864ba9aeff4d429552b95/src/DocXCore/Resources/styles.xml.gz
--------------------------------------------------------------------------------
/src/DocXCore/Section.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Xml.Linq;
3 |
4 | namespace Novacode
5 | {
6 | public class Section : Container
7 | {
8 |
9 | public SectionBreakType SectionBreakType;
10 |
11 | internal Section(DocX document, XElement xml) : base(document, xml)
12 | {
13 | }
14 |
15 | public List SectionParagraphs { get; set; }
16 | }
17 | }
--------------------------------------------------------------------------------
/src/DocXCore/TableOfContents.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Linq;
4 | using System.Xml;
5 | using System.Xml.Linq;
6 |
7 | namespace Novacode
8 | {
9 | ///
10 | /// Represents a table of contents in the document
11 | ///
12 | public class TableOfContents : DocXElement
13 | {
14 | #region TocBaseValues
15 |
16 | private const string HeaderStyle = "TOCHeading";
17 | private const int RightTabPos = 9350;
18 | #endregion
19 |
20 | private TableOfContents(DocX document, XElement xml, string headerStyle) : base(document, xml)
21 | {
22 | AssureUpdateField(document);
23 | AssureStyles(document, headerStyle);
24 | }
25 |
26 | internal static TableOfContents CreateTableOfContents(DocX document, string title, TableOfContentsSwitches switches, string headerStyle = null, int lastIncludeLevel = 3, int? rightTabPos = null)
27 | {
28 | var reader = XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocXmlBase, headerStyle ?? HeaderStyle, title, rightTabPos ?? RightTabPos, BuildSwitchString(switches, lastIncludeLevel))));
29 | var xml = XElement.Load(reader);
30 | return new TableOfContents(document, xml, headerStyle);
31 | }
32 |
33 | private void AssureUpdateField(DocX document)
34 | {
35 | if (document.settings.Descendants().Any(x => x.Name.Equals(DocX.w + "updateFields"))) return;
36 |
37 | var element = new XElement(XName.Get("updateFields", DocX.w.NamespaceName), new XAttribute(DocX.w + "val", true));
38 | document.settings.Root.Add(element);
39 | }
40 |
41 | private void AssureStyles(DocX document, string headerStyle)
42 | {
43 | if (!HasStyle(document, headerStyle, "paragraph"))
44 | {
45 | var reader = XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocHeadingStyleBase, headerStyle ?? HeaderStyle)));
46 | var xml = XElement.Load(reader);
47 | document.styles.Root.Add(xml);
48 | }
49 | if (!HasStyle(document, "TOC1", "paragraph"))
50 | {
51 | var reader = XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocElementStyleBase, "TOC1", "toc 1")));
52 | var xml = XElement.Load(reader);
53 | document.styles.Root.Add(xml);
54 | }
55 | if (!HasStyle(document, "TOC2", "paragraph"))
56 | {
57 | var reader = XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocElementStyleBase, "TOC2", "toc 2")));
58 | var xml = XElement.Load(reader);
59 | document.styles.Root.Add(xml);
60 | }
61 | if (!HasStyle(document, "TOC3", "paragraph"))
62 | {
63 | var reader = XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocElementStyleBase, "TOC3", "toc 3")));
64 | var xml = XElement.Load(reader);
65 | document.styles.Root.Add(xml);
66 | }
67 | if (!HasStyle(document, "TOC4", "paragraph"))
68 | {
69 | var reader = XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocElementStyleBase, "TOC4", "toc 4")));
70 | var xml = XElement.Load(reader);
71 | document.styles.Root.Add(xml);
72 | }
73 | if (!HasStyle(document, "Hyperlink", "character"))
74 | {
75 | var reader = XmlReader.Create(new StringReader(string.Format(XmlTemplateBases.TocHyperLinkStyleBase)));
76 | var xml = XElement.Load(reader);
77 | document.styles.Root.Add(xml);
78 | }
79 | }
80 |
81 | private bool HasStyle(DocX document, string value, string type)
82 | {
83 | return document.styles.Descendants().Any(x => x.Name.Equals(DocX.w + "style")&& (x.Attribute(DocX.w + "type") == null || x.Attribute(DocX.w + "type").Value.Equals(type)) && x.Attribute(DocX.w + "styleId") != null && x.Attribute(DocX.w + "styleId").Value.Equals(value));
84 | }
85 |
86 | private static string BuildSwitchString(TableOfContentsSwitches switches, int lastIncludeLevel)
87 | {
88 | var allSwitches = Enum.GetValues(typeof (TableOfContentsSwitches)).Cast();
89 | var switchString = "TOC";
90 | foreach (var s in allSwitches.Where(s => s != TableOfContentsSwitches.None && switches.HasFlag(s)))
91 | {
92 | switchString += " " + s.EnumDescription();
93 | if (s == TableOfContentsSwitches.O)
94 | {
95 | switchString += string.Format(" '{0}-{1}'", 1, lastIncludeLevel);
96 | }
97 | }
98 |
99 | return switchString;
100 | }
101 |
102 | }
103 | }
--------------------------------------------------------------------------------
/src/DocXCore/_BaseClasses.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO.Packaging;
3 | using System.Linq;
4 | using System.Xml.Linq;
5 |
6 | namespace Novacode
7 | {
8 | ///
9 | /// All DocX types are derived from DocXElement.
10 | /// This class contains properties which every element of a DocX must contain.
11 | ///
12 | public abstract class DocXElement
13 | {
14 | internal PackagePart mainPart;
15 | public PackagePart PackagePart { get { return mainPart; } set { mainPart = value; } }
16 |
17 | ///
18 | /// This is the actual Xml that gives this element substance.
19 | /// For example, a Paragraphs Xml might look something like the following
20 | ///
21 | ///
22 | /// Hello World!
23 | ///
24 | ///
25 | ///
26 |
27 | public XElement Xml { get; set; }
28 | ///
29 | /// This is a reference to the DocX object that this element belongs to.
30 | /// Every DocX element is connected to a document.
31 | ///
32 | internal DocX Document { get; set; }
33 | ///
34 | /// Store both the document and xml so that they can be accessed by derived types.
35 | ///
36 | /// The document that this element belongs to.
37 | /// The Xml that gives this element substance
38 | public DocXElement(DocX document, XElement xml)
39 | {
40 | this.Document = document;
41 | this.Xml = xml;
42 | }
43 | }
44 |
45 | ///
46 | /// This class provides functions for inserting new DocXElements before or after the current DocXElement.
47 | /// Only certain DocXElements can support these functions without creating invalid documents, at the moment these are Paragraphs and Table.
48 | ///
49 | public abstract class InsertBeforeOrAfter : DocXElement
50 | {
51 | public InsertBeforeOrAfter(DocX document, XElement xml) : base(document, xml) { }
52 |
53 | public virtual void InsertPageBreakBeforeSelf()
54 | {
55 | XElement p = new XElement
56 | (
57 | XName.Get("p", DocX.w.NamespaceName),
58 | new XElement
59 | (
60 | XName.Get("r", DocX.w.NamespaceName),
61 | new XElement
62 | (
63 | XName.Get("br", DocX.w.NamespaceName),
64 | new XAttribute(XName.Get("type", DocX.w.NamespaceName), "page")
65 | )
66 | )
67 | );
68 |
69 | Xml.AddBeforeSelf(p);
70 | }
71 |
72 | public virtual void InsertPageBreakAfterSelf()
73 | {
74 | XElement p = new XElement
75 | (
76 | XName.Get("p", DocX.w.NamespaceName),
77 | new XElement
78 | (
79 | XName.Get("r", DocX.w.NamespaceName),
80 | new XElement
81 | (
82 | XName.Get("br", DocX.w.NamespaceName),
83 | new XAttribute(XName.Get("type", DocX.w.NamespaceName), "page")
84 | )
85 | )
86 | );
87 |
88 | Xml.AddAfterSelf(p);
89 | }
90 |
91 | public virtual Paragraph InsertParagraphBeforeSelf(Paragraph p)
92 | {
93 | Xml.AddBeforeSelf(p.Xml);
94 | XElement newlyInserted = Xml.ElementsBeforeSelf().First();
95 |
96 | p.Xml = newlyInserted;
97 |
98 | return p;
99 | }
100 |
101 | public virtual Paragraph InsertParagraphAfterSelf(Paragraph p)
102 | {
103 | Xml.AddAfterSelf(p.Xml);
104 | XElement newlyInserted = Xml.ElementsAfterSelf().First();
105 |
106 | //Dmitchern
107 | if (this as Paragraph != null)
108 | {
109 | return new Paragraph(Document, newlyInserted, (this as Paragraph).endIndex);
110 | }
111 |
112 | 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
113 | return p;
114 | }
115 |
116 | public virtual Paragraph InsertParagraphBeforeSelf(string text)
117 | {
118 | return InsertParagraphBeforeSelf(text, false, new Formatting());
119 | }
120 |
121 | public virtual Paragraph InsertParagraphAfterSelf(string text)
122 | {
123 | return InsertParagraphAfterSelf(text, false, new Formatting());
124 | }
125 |
126 | public virtual Paragraph InsertParagraphBeforeSelf(string text, bool trackChanges)
127 | {
128 | return InsertParagraphBeforeSelf(text, trackChanges, new Formatting());
129 | }
130 |
131 | public virtual Paragraph InsertParagraphAfterSelf(string text, bool trackChanges)
132 | {
133 | return InsertParagraphAfterSelf(text, trackChanges, new Formatting());
134 | }
135 |
136 | public virtual Paragraph InsertParagraphBeforeSelf(string text, bool trackChanges, Formatting formatting)
137 | {
138 | XElement newParagraph = new XElement
139 | (
140 | XName.Get("p", DocX.w.NamespaceName), new XElement(XName.Get("pPr", DocX.w.NamespaceName)), HelperFunctions.FormatInput(text, formatting.Xml)
141 | );
142 |
143 | if (trackChanges)
144 | newParagraph = Paragraph.CreateEdit(EditType.ins, DateTime.Now, newParagraph);
145 |
146 | Xml.AddBeforeSelf(newParagraph);
147 | XElement newlyInserted = Xml.ElementsBeforeSelf().Last();
148 |
149 | return new Paragraph(Document, newlyInserted, -1);
150 | }
151 |
152 | public virtual Paragraph InsertParagraphAfterSelf(string text, bool trackChanges, Formatting formatting)
153 | {
154 | XElement newParagraph = new XElement
155 | (
156 | XName.Get("p", DocX.w.NamespaceName), new XElement(XName.Get("pPr", DocX.w.NamespaceName)), HelperFunctions.FormatInput(text, formatting.Xml)
157 | );
158 |
159 | if (trackChanges)
160 | newParagraph = Paragraph.CreateEdit(EditType.ins, DateTime.Now, newParagraph);
161 |
162 | Xml.AddAfterSelf(newParagraph);
163 | XElement newlyInserted = Xml.ElementsAfterSelf().First();
164 |
165 | Paragraph p = new Paragraph(Document, newlyInserted, -1);
166 |
167 | return p;
168 | }
169 |
170 | public virtual Table InsertTableAfterSelf(int rowCount, int columnCount)
171 | {
172 | XElement newTable = HelperFunctions.CreateTable(rowCount, columnCount);
173 | Xml.AddAfterSelf(newTable);
174 | XElement newlyInserted = Xml.ElementsAfterSelf().First();
175 |
176 | return new Table(Document, newlyInserted) { mainPart = mainPart };
177 | }
178 |
179 | public virtual Table InsertTableAfterSelf(Table t)
180 | {
181 | Xml.AddAfterSelf(t.Xml);
182 | XElement newlyInserted = Xml.ElementsAfterSelf().First();
183 | //Dmitchern
184 | return new Table(Document, newlyInserted) { mainPart = mainPart }; //return new table, dont affect parameter table
185 | }
186 |
187 | public virtual Table InsertTableBeforeSelf(int rowCount, int columnCount)
188 | {
189 | XElement newTable = HelperFunctions.CreateTable(rowCount, columnCount);
190 | Xml.AddBeforeSelf(newTable);
191 | XElement newlyInserted = Xml.ElementsBeforeSelf().Last();
192 |
193 | return new Table(Document, newlyInserted) { mainPart = mainPart };
194 | }
195 |
196 | public virtual Table InsertTableBeforeSelf(Table t)
197 | {
198 | Xml.AddBeforeSelf(t.Xml);
199 | XElement newlyInserted = Xml.ElementsBeforeSelf().Last();
200 |
201 | //Dmitchern
202 | return new Table(Document, newlyInserted) { mainPart=mainPart}; //return new table, dont affect parameter table
203 | }
204 | }
205 |
206 | public static class XmlTemplateBases
207 | {
208 | #region TocXml
209 | public const string TocXmlBase = @"
210 |
211 |
212 |
213 |
214 | \
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 | {1}
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 | {3}
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 | ";
267 | public const string TocHeadingStyleBase = @"
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 | ";
284 | public const string TocElementStyleBase = @"
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 | ";
297 | public const string TocHyperLinkStyleBase = @"
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 | ";
308 | #endregion
309 | }
310 | }
311 |
--------------------------------------------------------------------------------
/src/DocXCore/_Enumerations.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 |
4 | namespace Novacode
5 | {
6 |
7 | public enum ListItemType
8 | {
9 | Bulleted,
10 | Numbered
11 | }
12 |
13 | public enum SectionBreakType
14 | {
15 | defaultNextPage,
16 | evenPage,
17 | oddPage,
18 | continuous
19 | }
20 |
21 |
22 | public enum ContainerType
23 | {
24 | None,
25 | TOC,
26 | Section,
27 | Cell,
28 | Table,
29 | Header,
30 | Footer,
31 | Paragraph,
32 | Body
33 | }
34 |
35 | public enum PageNumberFormat
36 | {
37 | normal,
38 | roman
39 | }
40 |
41 | public enum BorderSize
42 | {
43 | one,
44 | two,
45 | three,
46 | four,
47 | five,
48 | six,
49 | seven,
50 | eight,
51 | nine
52 | }
53 |
54 | public enum EditRestrictions
55 | {
56 | none,
57 | readOnly,
58 | forms,
59 | comments,
60 | trackedChanges
61 | }
62 |
63 | ///
64 | /// Table Cell Border styles
65 | /// Added by lckuiper @ 20101117
66 | /// source: http://msdn.microsoft.com/en-us/library/documentformat.openxml.wordprocessing.tablecellborders.aspx
67 | ///
68 | public enum BorderStyle
69 | {
70 | Tcbs_none = 0,
71 | Tcbs_single,
72 | Tcbs_thick,
73 | Tcbs_double,
74 | Tcbs_dotted,
75 | Tcbs_dashed,
76 | Tcbs_dotDash,
77 | Tcbs_dotDotDash,
78 | Tcbs_triple,
79 | Tcbs_thinThickSmallGap,
80 | Tcbs_thickThinSmallGap,
81 | Tcbs_thinThickThinSmallGap,
82 | Tcbs_thinThickMediumGap,
83 | Tcbs_thickThinMediumGap,
84 | Tcbs_thinThickThinMediumGap,
85 | Tcbs_thinThickLargeGap,
86 | Tcbs_thickThinLargeGap,
87 | Tcbs_thinThickThinLargeGap,
88 | Tcbs_wave,
89 | Tcbs_doubleWave,
90 | Tcbs_dashSmallGap,
91 | Tcbs_dashDotStroked,
92 | Tcbs_threeDEmboss,
93 | Tcbs_threeDEngrave,
94 | Tcbs_outset,
95 | Tcbs_inset,
96 | Tcbs_nil
97 | }
98 |
99 | ///
100 | /// Table Cell Border Types
101 | /// Added by lckuiper @ 20101117
102 | /// source: http://msdn.microsoft.com/en-us/library/documentformat.openxml.wordprocessing.tablecellborders.aspx
103 | ///
104 | public enum TableCellBorderType
105 | {
106 | Top,
107 | Bottom,
108 | Left,
109 | Right,
110 | InsideH,
111 | InsideV,
112 | TopLeftToBottomRight,
113 | TopRightToBottomLeft
114 | }
115 |
116 | ///
117 | /// Table Border Types
118 | /// Added by lckuiper @ 20101117
119 | /// source: http://msdn.microsoft.com/en-us/library/documentformat.openxml.wordprocessing.tableborders.aspx
120 | ///
121 | public enum TableBorderType
122 | {
123 | Top,
124 | Bottom,
125 | Left,
126 | Right,
127 | InsideH,
128 | InsideV
129 | }
130 |
131 | // Patch 7398 added by lckuiper on Nov 16th 2010 @ 2:23 PM
132 | public enum VerticalAlignment
133 | {
134 | Top,
135 | Center,
136 | Bottom
137 | };
138 |
139 | public enum Orientation
140 | {
141 | Portrait,
142 | Landscape
143 | };
144 |
145 | public enum XmlDocument
146 | {
147 | Main,
148 | HeaderOdd,
149 | HeaderEven,
150 | HeaderFirst,
151 | FooterOdd,
152 | FooterEven,
153 | FooterFirst
154 | };
155 |
156 | public enum MatchFormattingOptions
157 | {
158 | ExactMatch,
159 | SubsetMatch
160 | };
161 |
162 | public enum Script
163 | {
164 | superscript,
165 | subscript,
166 | none
167 | }
168 |
169 | public enum Highlight
170 | {
171 | yellow,
172 | green,
173 | cyan,
174 | magenta,
175 | blue,
176 | red,
177 | darkBlue,
178 | darkCyan,
179 | darkGreen,
180 | darkMagenta,
181 | darkRed,
182 | darkYellow,
183 | darkGray,
184 | lightGray,
185 | black,
186 | none
187 | };
188 |
189 | public enum UnderlineStyle
190 | {
191 | none = 0,
192 | singleLine = 1,
193 | words = 2,
194 | doubleLine = 3,
195 | dotted = 4,
196 | thick = 6,
197 | dash = 7,
198 | dotDash = 9,
199 | dotDotDash = 10,
200 | wave = 11,
201 | dottedHeavy = 20,
202 | dashedHeavy = 23,
203 | dashDotHeavy = 25,
204 | dashDotDotHeavy = 26,
205 | dashLongHeavy = 27,
206 | dashLong = 39,
207 | wavyDouble = 43,
208 | wavyHeavy = 55,
209 | };
210 |
211 | public enum StrikeThrough
212 | {
213 | none,
214 | strike,
215 | doubleStrike
216 | };
217 |
218 | public enum Misc
219 | {
220 | none,
221 | shadow,
222 | outline,
223 | outlineShadow,
224 | emboss,
225 | engrave
226 | };
227 |
228 | ///
229 | /// Change the caps style of text, for use with Append and AppendLine.
230 | ///
231 | public enum CapsStyle
232 | {
233 | ///
234 | /// No caps, make all characters are lowercase.
235 | ///
236 | none,
237 |
238 | ///
239 | /// All caps, make every character uppercase.
240 | ///
241 | caps,
242 |
243 | ///
244 | /// Small caps, make all characters capital but with a small font size.
245 | ///
246 | smallCaps
247 | };
248 |
249 | ///
250 | /// Designs\Styles that can be applied to a table.
251 | ///
252 | public enum TableDesign
253 | {
254 | Custom,
255 | TableNormal,
256 | TableGrid,
257 | LightShading,
258 | LightShadingAccent1,
259 | LightShadingAccent2,
260 | LightShadingAccent3,
261 | LightShadingAccent4,
262 | LightShadingAccent5,
263 | LightShadingAccent6,
264 | LightList,
265 | LightListAccent1,
266 | LightListAccent2,
267 | LightListAccent3,
268 | LightListAccent4,
269 | LightListAccent5,
270 | LightListAccent6,
271 | LightGrid,
272 | LightGridAccent1,
273 | LightGridAccent2,
274 | LightGridAccent3,
275 | LightGridAccent4,
276 | LightGridAccent5,
277 | LightGridAccent6,
278 | MediumShading1,
279 | MediumShading1Accent1,
280 | MediumShading1Accent2,
281 | MediumShading1Accent3,
282 | MediumShading1Accent4,
283 | MediumShading1Accent5,
284 | MediumShading1Accent6,
285 | MediumShading2,
286 | MediumShading2Accent1,
287 | MediumShading2Accent2,
288 | MediumShading2Accent3,
289 | MediumShading2Accent4,
290 | MediumShading2Accent5,
291 | MediumShading2Accent6,
292 | MediumList1,
293 | MediumList1Accent1,
294 | MediumList1Accent2,
295 | MediumList1Accent3,
296 | MediumList1Accent4,
297 | MediumList1Accent5,
298 | MediumList1Accent6,
299 | MediumList2,
300 | MediumList2Accent1,
301 | MediumList2Accent2,
302 | MediumList2Accent3,
303 | MediumList2Accent4,
304 | MediumList2Accent5,
305 | MediumList2Accent6,
306 | MediumGrid1,
307 | MediumGrid1Accent1,
308 | MediumGrid1Accent2,
309 | MediumGrid1Accent3,
310 | MediumGrid1Accent4,
311 | MediumGrid1Accent5,
312 | MediumGrid1Accent6,
313 | MediumGrid2,
314 | MediumGrid2Accent1,
315 | MediumGrid2Accent2,
316 | MediumGrid2Accent3,
317 | MediumGrid2Accent4,
318 | MediumGrid2Accent5,
319 | MediumGrid2Accent6,
320 | MediumGrid3,
321 | MediumGrid3Accent1,
322 | MediumGrid3Accent2,
323 | MediumGrid3Accent3,
324 | MediumGrid3Accent4,
325 | MediumGrid3Accent5,
326 | MediumGrid3Accent6,
327 | DarkList,
328 | DarkListAccent1,
329 | DarkListAccent2,
330 | DarkListAccent3,
331 | DarkListAccent4,
332 | DarkListAccent5,
333 | DarkListAccent6,
334 | ColorfulShading,
335 | ColorfulShadingAccent1,
336 | ColorfulShadingAccent2,
337 | ColorfulShadingAccent3,
338 | ColorfulShadingAccent4,
339 | ColorfulShadingAccent5,
340 | ColorfulShadingAccent6,
341 | ColorfulList,
342 | ColorfulListAccent1,
343 | ColorfulListAccent2,
344 | ColorfulListAccent3,
345 | ColorfulListAccent4,
346 | ColorfulListAccent5,
347 | ColorfulListAccent6,
348 | ColorfulGrid,
349 | ColorfulGridAccent1,
350 | ColorfulGridAccent2,
351 | ColorfulGridAccent3,
352 | ColorfulGridAccent4,
353 | ColorfulGridAccent5,
354 | ColorfulGridAccent6,
355 | None
356 | };
357 |
358 | ///
359 | /// How a Table should auto resize.
360 | ///
361 | public enum AutoFit
362 | {
363 | ///
364 | /// Autofit to Table contents.
365 | ///
366 | Contents,
367 |
368 | ///
369 | /// Autofit to Window.
370 | ///
371 | Window,
372 |
373 | ///
374 | /// Autofit to Column width.
375 | ///
376 | ColumnWidth,
377 | ///
378 | /// Autofit to Fixed column width
379 | ///
380 | Fixed
381 | };
382 |
383 | public enum RectangleShapes
384 | {
385 | rect,
386 | roundRect,
387 | snip1Rect,
388 | snip2SameRect,
389 | snip2DiagRect,
390 | snipRoundRect,
391 | round1Rect,
392 | round2SameRect,
393 | round2DiagRect
394 | };
395 |
396 | public enum BasicShapes
397 | {
398 | ellipse,
399 | triangle,
400 | rtTriangle,
401 | parallelogram,
402 | trapezoid,
403 | diamond,
404 | pentagon,
405 | hexagon,
406 | heptagon,
407 | octagon,
408 | decagon,
409 | dodecagon,
410 | pie,
411 | chord,
412 | teardrop,
413 | frame,
414 | halfFrame,
415 | corner,
416 | diagStripe,
417 | plus,
418 | plaque,
419 | can,
420 | cube,
421 | bevel,
422 | donut,
423 | noSmoking,
424 | blockArc,
425 | foldedCorner,
426 | smileyFace,
427 | heart,
428 | lightningBolt,
429 | sun,
430 | moon,
431 | cloud,
432 | arc,
433 | backetPair,
434 | bracePair,
435 | leftBracket,
436 | rightBracket,
437 | leftBrace,
438 | rightBrace
439 | };
440 |
441 | public enum BlockArrowShapes
442 | {
443 | rightArrow,
444 | leftArrow,
445 | upArrow,
446 | downArrow,
447 | leftRightArrow,
448 | upDownArrow,
449 | quadArrow,
450 | leftRightUpArrow,
451 | bentArrow,
452 | uturnArrow,
453 | leftUpArrow,
454 | bentUpArrow,
455 | curvedRightArrow,
456 | curvedLeftArrow,
457 | curvedUpArrow,
458 | curvedDownArrow,
459 | stripedRightArrow,
460 | notchedRightArrow,
461 | homePlate,
462 | chevron,
463 | rightArrowCallout,
464 | downArrowCallout,
465 | leftArrowCallout,
466 | upArrowCallout,
467 | leftRightArrowCallout,
468 | quadArrowCallout,
469 | circularArrow
470 | };
471 |
472 | public enum EquationShapes
473 | {
474 | mathPlus,
475 | mathMinus,
476 | mathMultiply,
477 | mathDivide,
478 | mathEqual,
479 | mathNotEqual
480 | };
481 |
482 | public enum FlowchartShapes
483 | {
484 | flowChartProcess,
485 | flowChartAlternateProcess,
486 | flowChartDecision,
487 | flowChartInputOutput,
488 | flowChartPredefinedProcess,
489 | flowChartInternalStorage,
490 | flowChartDocument,
491 | flowChartMultidocument,
492 | flowChartTerminator,
493 | flowChartPreparation,
494 | flowChartManualInput,
495 | flowChartManualOperation,
496 | flowChartConnector,
497 | flowChartOffpageConnector,
498 | flowChartPunchedCard,
499 | flowChartPunchedTape,
500 | flowChartSummingJunction,
501 | flowChartOr,
502 | flowChartCollate,
503 | flowChartSort,
504 | flowChartExtract,
505 | flowChartMerge,
506 | flowChartOnlineStorage,
507 | flowChartDelay,
508 | flowChartMagneticTape,
509 | flowChartMagneticDisk,
510 | flowChartMagneticDrum,
511 | flowChartDisplay
512 | };
513 |
514 | public enum StarAndBannerShapes
515 | {
516 | irregularSeal1,
517 | irregularSeal2,
518 | star4,
519 | star5,
520 | star6,
521 | star7,
522 | star8,
523 | star10,
524 | star12,
525 | star16,
526 | star24,
527 | star32,
528 | ribbon,
529 | ribbon2,
530 | ellipseRibbon,
531 | ellipseRibbon2,
532 | verticalScroll,
533 | horizontalScroll,
534 | wave,
535 | doubleWave
536 | };
537 |
538 | public enum CalloutShapes
539 | {
540 | wedgeRectCallout,
541 | wedgeRoundRectCallout,
542 | wedgeEllipseCallout,
543 | cloudCallout,
544 | borderCallout1,
545 | borderCallout2,
546 | borderCallout3,
547 | accentCallout1,
548 | accentCallout2,
549 | accentCallout3,
550 | callout1,
551 | callout2,
552 | callout3,
553 | accentBorderCallout1,
554 | accentBorderCallout2,
555 | accentBorderCallout3
556 | };
557 |
558 | ///
559 | /// Text alignment of a Paragraph.
560 | ///
561 | public enum Alignment
562 | {
563 | ///
564 | /// Align Paragraph to the left.
565 | ///
566 | left,
567 |
568 | ///
569 | /// Align Paragraph as centered.
570 | ///
571 | center,
572 |
573 | ///
574 | /// Align Paragraph to the right.
575 | ///
576 | right,
577 |
578 | ///
579 | /// (Justified) Align Paragraph to both the left and right margins, adding extra space between content as necessary.
580 | ///
581 | both
582 | };
583 |
584 | public enum Direction
585 | {
586 | LeftToRight,
587 | RightToLeft
588 | };
589 |
590 | ///
591 | /// Paragraph edit types
592 | ///
593 | internal enum EditType
594 | {
595 | ///
596 | /// A ins is a tracked insertion
597 | ///
598 | ins,
599 |
600 | ///
601 | /// A del is tracked deletion
602 | ///
603 | del
604 | }
605 |
606 | ///
607 | /// Custom property types.
608 | ///
609 | internal enum CustomPropertyType
610 | {
611 | ///
612 | /// System.String
613 | ///
614 | Text,
615 |
616 | ///
617 | /// System.DateTime
618 | ///
619 | Date,
620 |
621 | ///
622 | /// System.Int32
623 | ///
624 | NumberInteger,
625 |
626 | ///
627 | /// System.Double
628 | ///
629 | NumberDecimal,
630 |
631 | ///
632 | /// System.Boolean
633 | ///
634 | YesOrNo
635 | }
636 |
637 | ///
638 | /// Text types in a Run
639 | ///
640 | public enum RunTextType
641 | {
642 | ///
643 | /// System.String
644 | ///
645 | Text,
646 |
647 | ///
648 | /// System.String
649 | ///
650 | DelText,
651 | }
652 | public enum LineSpacingType
653 | {
654 | Line,
655 | Before,
656 | After
657 | }
658 |
659 | public enum LineSpacingTypeAuto
660 | {
661 | AutoBefore,
662 | AutoAfter,
663 | Auto,
664 | None
665 | }
666 |
667 | ///
668 | /// Cell margin for all sides of the table cell.
669 | ///
670 | public enum TableCellMarginType
671 | {
672 | ///
673 | /// The left cell margin.
674 | ///
675 | left,
676 | ///
677 | /// The right cell margin.
678 | ///
679 | right,
680 | ///
681 | /// The bottom cell margin.
682 | ///
683 | bottom,
684 | ///
685 | /// The top cell margin.
686 | ///
687 | top
688 | }
689 |
690 | public enum HeadingType
691 | {
692 | [Description("Heading1")]
693 | Heading1,
694 |
695 | [Description("Heading2")]
696 | Heading2,
697 |
698 | [Description("Heading3")]
699 | Heading3,
700 |
701 | [Description("Heading4")]
702 | Heading4,
703 |
704 | [Description("Heading5")]
705 | Heading5,
706 |
707 | [Description("Heading6")]
708 | Heading6,
709 |
710 | [Description("Heading7")]
711 | Heading7,
712 |
713 | [Description("Heading8")]
714 | Heading8,
715 |
716 | [Description("Heading9")]
717 | Heading9,
718 |
719 |
720 | /*
721 | * The Character Based Headings below do not work in the same way as the headings 1-9 above, but appear on the same list in word.
722 | * I have kept them here for reference in case somebody else things its just a matter of adding them in to gain extra headings
723 | */
724 | #region Other character (NOT paragraph) based Headings
725 | //[Description("NoSpacing")]
726 | //NoSpacing,
727 |
728 | //[Description("Title")]
729 | //Title,
730 |
731 | //[Description("Subtitle")]
732 | //Subtitle,
733 |
734 | //[Description("Quote")]
735 | //Quote,
736 |
737 | //[Description("IntenseQuote")]
738 | //IntenseQuote,
739 |
740 | //[Description("Emphasis")]
741 | //Emphasis,
742 |
743 | //[Description("IntenseEmphasis")]
744 | //IntenseEmphasis,
745 |
746 | //[Description("Strong")]
747 | //Strong,
748 |
749 | //[Description("ListParagraph")]
750 | //ListParagraph,
751 |
752 | //[Description("SubtleReference")]
753 | //SubtleReference,
754 |
755 | //[Description("IntenseReference")]
756 | //IntenseReference,
757 |
758 | //[Description("BookTitle")]
759 | //BookTitle,
760 | #endregion
761 |
762 |
763 | }
764 | public enum TextDirection
765 | {
766 | btLr,
767 | right
768 | };
769 |
770 | ///
771 | /// Represents the switches set on a TOC.
772 | ///
773 | [Flags]
774 | public enum TableOfContentsSwitches
775 | {
776 | None = 0 << 0,
777 | [Description("\\a")]
778 | A = 1 << 0,
779 | [Description("\\b")]
780 | B = 1 << 1,
781 | [Description("\\c")]
782 | C = 1 << 2,
783 | [Description("\\d")]
784 | D = 1 << 3,
785 | [Description("\\f")]
786 | F = 1 << 4,
787 | [Description("\\h")]
788 | H = 1 << 5,
789 | [Description("\\l")]
790 | L = 1 << 6,
791 | [Description("\\n")]
792 | N = 1 << 7,
793 | [Description("\\o")]
794 | O = 1 << 8,
795 | [Description("\\p")]
796 | P = 1 << 9,
797 | [Description("\\s")]
798 | S = 1 << 10,
799 | [Description("\\t")]
800 | T = 1 << 11,
801 | [Description("\\u")]
802 | U = 1 << 12,
803 | [Description("\\w")]
804 | W = 1 << 13,
805 | [Description("\\x")]
806 | X = 1 << 14,
807 | [Description("\\z")]
808 | Z = 1 << 15,
809 | }
810 |
811 | }
--------------------------------------------------------------------------------
/src/DocXCore/_Extensions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Drawing;
4 | using System.Xml.Linq;
5 |
6 | namespace Novacode
7 | {
8 | internal static class Extensions
9 | {
10 | internal static string ToHex(this Color source)
11 | {
12 | byte red = source.R;
13 | byte green = source.G;
14 | byte blue = source.B;
15 |
16 | string redHex = red.ToString("X");
17 | if (redHex.Length < 2)
18 | redHex = "0" + redHex;
19 |
20 | string blueHex = blue.ToString("X");
21 | if (blueHex.Length < 2)
22 | blueHex = "0" + blueHex;
23 |
24 | string greenHex = green.ToString("X");
25 | if (greenHex.Length < 2)
26 | greenHex = "0" + greenHex;
27 |
28 | return string.Format("{0}{1}{2}", redHex, greenHex, blueHex);
29 | }
30 |
31 | public static void Flatten(this XElement e, XName name, List flat)
32 | {
33 | // Add this element (without its children) to the flat list.
34 | XElement clone = CloneElement(e);
35 | clone.Elements().Remove();
36 |
37 | // Filter elements using XName.
38 | if (clone.Name == name)
39 | flat.Add(clone);
40 |
41 | // Process the children.
42 | if (e.HasElements)
43 | foreach (XElement elem in e.Elements(name)) // Filter elements using XName
44 | elem.Flatten(name, flat);
45 | }
46 |
47 | static XElement CloneElement(XElement element)
48 | {
49 | return new XElement(element.Name,
50 | element.Attributes(),
51 | element.Nodes().Select(n =>
52 | {
53 | XElement e = n as XElement;
54 | if (e != null)
55 | return CloneElement(e);
56 | return n;
57 | }
58 | )
59 | );
60 | }
61 |
62 | public static string GetAttribute(this XElement el, XName name, string defaultValue = "")
63 | {
64 | var attr = el.Attribute(name);
65 | if (attr != null)
66 | return attr.Value;
67 | return defaultValue;
68 | }
69 |
70 | ///
71 | /// Sets margin for all the pages in a Dox document in Inches. (Written by Shashwat Tripathi)
72 | ///
73 | ///
74 | /// Margin from the Top. Leave -1 for no change
75 | /// Margin from the Bottom. Leave -1 for no change
76 | /// Margin from the Right. Leave -1 for no change
77 | /// Margin from the Left. Leave -1 for no change
78 | public static void SetMargin(this DocX document, float top, float bottom, float right, float left)
79 | {
80 | XNamespace ab = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
81 | var tempElement = document.PageLayout.Xml.Descendants(ab + "pgMar");
82 |
83 | foreach (var item in tempElement)
84 | {
85 | if (left != -1)
86 | item.SetAttributeValue(ab + "left", (1440 * left) / 1);
87 | if (right != -1)
88 | item.SetAttributeValue(ab + "right", (1440 * right) / 1);
89 | if (top != -1)
90 | item.SetAttributeValue(ab + "top", (1440 * top) / 1);
91 | if (bottom != -1)
92 | item.SetAttributeValue(ab + "bottom", (1440 * bottom) / 1);
93 | }
94 | }
95 | }
96 |
97 | }
98 |
--------------------------------------------------------------------------------