소스 검색

FIx for "removing paragraphs from cell in table does not work"

Patch provided by Bartosz Węgielewski
master
MadBoy_cp 12 년 전
부모
커밋
f80ab8c2aa
6개의 변경된 파일234개의 추가작업 그리고 130개의 파일을 삭제
  1. 42
    2
      DocX/Container.cs
  2. 7
    3
      DocX/DocX.cs
  3. 7
    3
      DocX/Footer.cs
  4. 7
    3
      DocX/Header.cs
  5. 115
    114
      DocX/Table.cs
  6. 56
    5
      UnitTests/DocXUnitTests.cs

+ 42
- 2
DocX/Container.cs 파일 보기

@@ -5,6 +5,7 @@ using System.Xml.Linq;
using System.IO.Packaging;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Collections.ObjectModel;
namespace Novacode
{
@@ -56,7 +57,7 @@ namespace Novacode
/// }// Release this document from memory.
/// </code>
/// </example>
public virtual List<Paragraph> Paragraphs
public virtual ReadOnlyCollection<Paragraph> Paragraphs
{
get
{
@@ -75,10 +76,49 @@ namespace Novacode
}
}
return paragraphs;
return paragraphs.AsReadOnly();
}
}
// <summary>
/// Removes paragraph at specified position
/// </summary>
/// <param name="index">Index of paragraph to remove</param>
/// <returns>True if removed</returns>
public bool RemoveParagraphAt(int index)
{
int i = 0;
foreach (var paragraph in Xml.Descendants(DocX.w + "p"))
{
if (i == index)
{
paragraph.Remove();
return true;
}
++i;
}
return false;
}
/// <summary>
/// Removes paragraph
/// </summary>
/// <param name="paragraph">Paragraph to remove</param>
/// <returns>True if removed</returns>
public bool RemoveParagraph(Paragraph p)
{
foreach (var paragraph in Xml.Descendants(DocX.w + "p"))
{
if (paragraph.Equals(p.Xml))
{
paragraph.Remove();
return true;
}
}
return false;
}
public virtual List<Section> Sections

+ 7
- 3
DocX/DocX.cs 파일 보기

@@ -8,6 +8,7 @@ using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Linq;
using System.Collections.ObjectModel;
namespace Novacode
{
@@ -3881,12 +3882,15 @@ namespace Novacode
return paragraphs.ToArray();
}
public override List<Paragraph> Paragraphs
public override ReadOnlyCollection<Paragraph> Paragraphs
{
get
{
List<Paragraph> l = base.Paragraphs;
l.ForEach(x => x.PackagePart = mainPart);
ReadOnlyCollection<Paragraph> l = base.Paragraphs;
foreach (var paragraph in l)
{
paragraph.PackagePart = mainPart;
}
return l;
}
}

+ 7
- 3
DocX/Footer.cs 파일 보기

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Xml.Linq;
using System.IO.Packaging;
using System.Collections.ObjectModel;
namespace Novacode
{
@@ -116,12 +117,15 @@ namespace Novacode
return p;
}
public override List<Paragraph> Paragraphs
public override ReadOnlyCollection<Paragraph> Paragraphs
{
get
{
List<Paragraph> l = base.Paragraphs;
l.ForEach(x => x.mainPart = mainPart);
ReadOnlyCollection<Paragraph> l = base.Paragraphs;
foreach (var paragraph in l)
{
paragraph.mainPart = mainPart;
}
return l;
}
}

+ 7
- 3
DocX/Header.cs 파일 보기

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.IO.Packaging;
using System.Collections.ObjectModel;
namespace Novacode
{
@@ -122,12 +123,15 @@ namespace Novacode
}
public override List<Paragraph> Paragraphs
public override ReadOnlyCollection<Paragraph> Paragraphs
{
get
{
List<Paragraph> l = base.Paragraphs;
l.ForEach(x => x.mainPart = mainPart);
ReadOnlyCollection<Paragraph> l = base.Paragraphs;
foreach (var paragraph in l)
{
paragraph.mainPart = mainPart;
}
return l;
}
}

+ 115
- 114
DocX/Table.cs 파일 보기

@@ -6,6 +6,7 @@ using System.IO.Packaging;
using System.IO;
using System.Drawing;
using System.Globalization;
using System.Collections.ObjectModel;
namespace Novacode
{
@@ -1797,79 +1798,79 @@ namespace Novacode
/// </example>
/// <param name="borderType">The table border to set</param>
/// <param name="border">Border object to set the table border</param>
public void SetBorder(TableBorderType borderType, Border border)
{
/*
* Get the tblPr (table properties) element for this Table,
* null will be return if no such element exists.
*/
XElement tblPr = Xml.Element(XName.Get("tblPr", DocX.w.NamespaceName));
if (tblPr == null)
{
Xml.SetElementValue(XName.Get("tblPr", DocX.w.NamespaceName), string.Empty);
tblPr = Xml.Element(XName.Get("tblPr", DocX.w.NamespaceName));
}
/*
* Get the tblBorders (table borders) element for this Table,
* null will be return if no such element exists.
*/
XElement tblBorders = tblPr.Element(XName.Get("tblBorders", DocX.w.NamespaceName));
if (tblBorders == null)
{
tblPr.SetElementValue(XName.Get("tblBorders", DocX.w.NamespaceName), string.Empty);
tblBorders = tblPr.Element(XName.Get("tblBorders", DocX.w.NamespaceName));
}
/*
* Get the 'borderType' (table border) element for this Table,
* null will be return if no such element exists.
*/
string tbordertype;
tbordertype = borderType.ToString();
// only lower the first char of string (because of insideH and insideV)
tbordertype = tbordertype.Substring(0, 1).ToLower() + tbordertype.Substring(1);
XElement tblBorderType = tblBorders.Element(XName.Get(borderType.ToString(), DocX.w.NamespaceName));
if (tblBorderType == null)
{
tblBorders.SetElementValue(XName.Get(tbordertype, DocX.w.NamespaceName), string.Empty);
tblBorderType = tblBorders.Element(XName.Get(tbordertype, DocX.w.NamespaceName));
}
// get string value of border style
string borderstyle = border.Tcbs.ToString().Substring(5);
borderstyle = borderstyle.Substring(0, 1).ToLower() + borderstyle.Substring(1);
// The val attribute is used for the border style
tblBorderType.SetAttributeValue(XName.Get("val", DocX.w.NamespaceName), borderstyle);
if (border.Tcbs != BorderStyle.Tcbs_nil)
{
int size;
switch (border.Size)
{
case BorderSize.one: size = 2; break;
case BorderSize.two: size = 4; break;
case BorderSize.three: size = 6; break;
case BorderSize.four: size = 8; break;
case BorderSize.five: size = 12; break;
case BorderSize.six: size = 18; break;
case BorderSize.seven: size = 24; break;
case BorderSize.eight: size = 36; break;
case BorderSize.nine: size = 48; break;
default: size = 2; break;
}
// The sz attribute is used for the border size
tblBorderType.SetAttributeValue(XName.Get("sz", DocX.w.NamespaceName), (size).ToString());
// The space attribute is used for the cell spacing (probably '0')
tblBorderType.SetAttributeValue(XName.Get("space", DocX.w.NamespaceName), (border.Space).ToString());
// The color attribute is used for the border color
tblBorderType.SetAttributeValue(XName.Get("color", DocX.w.NamespaceName), ColorTranslator.ToHtml(border.Color));
}
public void SetBorder(TableBorderType borderType, Border border)
{
/*
* Get the tblPr (table properties) element for this Table,
* null will be return if no such element exists.
*/
XElement tblPr = Xml.Element(XName.Get("tblPr", DocX.w.NamespaceName));
if (tblPr == null)
{
Xml.SetElementValue(XName.Get("tblPr", DocX.w.NamespaceName), string.Empty);
tblPr = Xml.Element(XName.Get("tblPr", DocX.w.NamespaceName));
}
/*
* Get the tblBorders (table borders) element for this Table,
* null will be return if no such element exists.
*/
XElement tblBorders = tblPr.Element(XName.Get("tblBorders", DocX.w.NamespaceName));
if (tblBorders == null)
{
tblPr.SetElementValue(XName.Get("tblBorders", DocX.w.NamespaceName), string.Empty);
tblBorders = tblPr.Element(XName.Get("tblBorders", DocX.w.NamespaceName));
}
/*
* Get the 'borderType' (table border) element for this Table,
* null will be return if no such element exists.
*/
string tbordertype;
tbordertype = borderType.ToString();
// only lower the first char of string (because of insideH and insideV)
tbordertype = tbordertype.Substring(0, 1).ToLower() + tbordertype.Substring(1);
XElement tblBorderType = tblBorders.Element(XName.Get(borderType.ToString(), DocX.w.NamespaceName));
if (tblBorderType == null)
{
tblBorders.SetElementValue(XName.Get(tbordertype, DocX.w.NamespaceName), string.Empty);
tblBorderType = tblBorders.Element(XName.Get(tbordertype, DocX.w.NamespaceName));
}
// get string value of border style
string borderstyle = border.Tcbs.ToString().Substring(5);
borderstyle = borderstyle.Substring(0, 1).ToLower() + borderstyle.Substring(1);
// The val attribute is used for the border style
tblBorderType.SetAttributeValue(XName.Get("val", DocX.w.NamespaceName), borderstyle);
if (border.Tcbs != BorderStyle.Tcbs_nil)
{
int size;
switch (border.Size)
{
case BorderSize.one: size = 2; break;
case BorderSize.two: size = 4; break;
case BorderSize.three: size = 6; break;
case BorderSize.four: size = 8; break;
case BorderSize.five: size = 12; break;
case BorderSize.six: size = 18; break;
case BorderSize.seven: size = 24; break;
case BorderSize.eight: size = 36; break;
case BorderSize.nine: size = 48; break;
default: size = 2; break;
}
// The sz attribute is used for the border size
tblBorderType.SetAttributeValue(XName.Get("sz", DocX.w.NamespaceName), (size).ToString());
// The space attribute is used for the cell spacing (probably '0')
tblBorderType.SetAttributeValue(XName.Get("space", DocX.w.NamespaceName), (border.Space).ToString());
// The color attribute is used for the border color
tblBorderType.SetAttributeValue(XName.Get("color", DocX.w.NamespaceName), ColorTranslator.ToHtml(border.Color));
}
}
/// <summary>
@@ -2078,7 +2079,7 @@ namespace Novacode
table.Remove();
}
public override List<Paragraph> Paragraphs
public override ReadOnlyCollection<Paragraph> Paragraphs
{
get
{
@@ -2091,7 +2092,7 @@ namespace Novacode
foreach (Paragraph p in paragraphs)
p.PackagePart = table.mainPart;
return paragraphs;
return paragraphs.AsReadOnly();
}
}
@@ -2182,43 +2183,43 @@ namespace Novacode
}
}
/// <summary>
/// Set to true to make this row the table header row that will be repeated on each page
/// </summary>
public bool TableHeader
{
get
{
XElement trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName));
XElement tblHeader = trPr.Element(XName.Get("tblHeader", DocX.w.NamespaceName));
if (tblHeader == null)
{
return false;
}
else
{
return true;
}
}
set
{
XElement trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName));
if (trPr == null)
{
Xml.SetElementValue(XName.Get("trPr", DocX.w.NamespaceName), string.Empty);
trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName));
}
XElement tblHeader = trPr.Element(XName.Get("tblHeader", DocX.w.NamespaceName));
if (tblHeader == null && value)
{
trPr.SetElementValue(XName.Get("tblHeader", DocX.w.NamespaceName), string.Empty);
}
if (tblHeader != null && !value)
{
tblHeader.Remove();
}
}
}
/// <summary>
/// Set to true to make this row the table header row that will be repeated on each page
/// </summary>
public bool TableHeader
{
get
{
XElement trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName));
XElement tblHeader = trPr.Element(XName.Get("tblHeader", DocX.w.NamespaceName));
if (tblHeader == null)
{
return false;
}
else
{
return true;
}
}
set
{
XElement trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName));
if (trPr == null)
{
Xml.SetElementValue(XName.Get("trPr", DocX.w.NamespaceName), string.Empty);
trPr = Xml.Element(XName.Get("trPr", DocX.w.NamespaceName));
}
XElement tblHeader = trPr.Element(XName.Get("tblHeader", DocX.w.NamespaceName));
if (tblHeader == null && value)
{
trPr.SetElementValue(XName.Get("tblHeader", DocX.w.NamespaceName), string.Empty);
}
if (tblHeader != null && !value)
{
tblHeader.Remove();
}
}
}
/// <summary>
@@ -2358,11 +2359,11 @@ namespace Novacode
this.mainPart = row.mainPart;
}
public override List<Paragraph> Paragraphs
public override ReadOnlyCollection<Paragraph> Paragraphs
{
get
{
List<Paragraph> paragraphs = base.Paragraphs;
ReadOnlyCollection<Paragraph> paragraphs = base.Paragraphs;
foreach (Paragraph p in paragraphs)
p.PackagePart = row.table.mainPart;

+ 56
- 5
UnitTests/DocXUnitTests.cs 파일 보기

@@ -8,6 +8,7 @@ using System.Reflection;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.ObjectModel;
namespace UnitTests
{
@@ -1146,7 +1147,7 @@ namespace UnitTests
using (DocX document = DocX.Load(_directoryWithFiles + "Paragraphs.docx"))
{
// Extract the Paragraphs from this document.
List<Paragraph> paragraphs = document.Paragraphs;
ReadOnlyCollection<Paragraph> paragraphs = document.Paragraphs;
// There should be 3 Paragraphs in this document.
Assert.IsTrue(paragraphs.Count() == 3);
@@ -1167,7 +1168,11 @@ namespace UnitTests
Assert.IsTrue(p3_text == "Paragraph 3");
// Its important that each Paragraph knows the PackagePart it belongs to.
document.Paragraphs.ForEach(p => Assert.IsTrue(p.PackagePart.Uri.ToString() == package_part_document));
foreach (var paragraph in document.Paragraphs)
{
Assert.IsTrue(paragraph.PackagePart.Uri.ToString() == package_part_document);
}
// Test the saving of the document.
document.SaveAs(FileTemp);
@@ -1332,7 +1337,7 @@ namespace UnitTests
{
using (DocX document = DocX.Load(_directoryWithFiles + "Tables.docx"))
{
List<Paragraph> paragraphs = document.Paragraphs;
ReadOnlyCollection<Paragraph> paragraphs = document.Paragraphs;
Paragraph p1 = paragraphs[0];
@@ -1821,9 +1826,9 @@ namespace UnitTests
{
Paragraph p = document.InsertParagraph();
p.Append("Hello World").Font(new FontFamily("Century"));
p.Append("Hello World").Font(new FontFamily("Symbol"));
Assert.AreEqual(p.MagicText[0].formatting.FontFamily.Name, "Century");
Assert.AreEqual(p.MagicText[0].formatting.FontFamily.Name, "Symbol");
document.Save();
}
@@ -1871,6 +1876,52 @@ namespace UnitTests
}
}
[TestMethod]
public void Test_Table_RemoveParagraphs()
{
MemoryStream memoryStream;
DocX document;
memoryStream = new MemoryStream();
document = DocX.Create(memoryStream);
// Add a Table into the document.
Table table = document.AddTable(1, 4); // 1 row, 4 cells
table.Design = TableDesign.TableGrid;
table.Alignment = Alignment.center;
// Edit row
var row = table.Rows[0];
// Fill 1st paragraph
row.Cells[0].Paragraphs.ElementAt(0).Append("Paragraph 1");
// Fill 2nd paragraph
var secondParagraph = row.Cells[0].InsertParagraph("Paragraph 2");
// Check number of paragraphs
Assert.AreEqual(2, row.Cells[0].Paragraphs.Count());
// Remove 1st paragraph
var deleted = row.Cells[0].RemoveParagraphAt(0);
Assert.IsTrue(deleted);
// Check number of paragraphs
Assert.AreEqual(1, row.Cells[0].Paragraphs.Count());
// Remove 3rd (nonexisting) paragraph
deleted = row.Cells[0].RemoveParagraphAt(3);
Assert.IsFalse(deleted);
//check number of paragraphs
Assert.AreEqual(1, row.Cells[0].Paragraphs.Count());
// Remove secondParagraph (this time the only one) paragraph
deleted = row.Cells[0].RemoveParagraph(secondParagraph);
Assert.IsTrue(deleted);
Assert.AreEqual(0, row.Cells[0].Paragraphs.Count());
// Remove last paragraph once again - this time this paragraph does not exists
deleted = row.Cells[0].RemoveParagraph(secondParagraph);
Assert.IsFalse(deleted);
Assert.AreEqual(0, row.Cells[0].Paragraphs.Count());
}
}
}

Loading…
취소
저장