Просмотр исходного кода

More testing yielded a case where the new inline Hyperlink support broke down.

I have fixed this issue now and I think thats it. I am now happy with the Hyperlink implementation.
master
coffeycathal_cp 14 лет назад
Родитель
Сommit
59652d225b
4 измененных файлов: 118 добавлений и 10 удалений
  1. 4
    1
      DocX.sln
  2. 16
    3
      DocX/Hyperlink.cs
  3. 58
    6
      DocX/Paragraph.cs
  4. 40
    0
      UnitTests/UnitTest1.cs

+ 4
- 1
DocX.sln Просмотреть файл

EndProject EndProject
Global Global
GlobalSection(TeamFoundationVersionControl) = preSolution GlobalSection(TeamFoundationVersionControl) = preSolution
SccNumberOfProjects = 4
SccNumberOfProjects = 5
SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C} SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
SccTeamFoundationServer = https://tfs.codeplex.com/tfs/tfs08 SccTeamFoundationServer = https://tfs.codeplex.com/tfs/tfs08
SccLocalPath0 = . SccLocalPath0 = .
SccProjectUniqueName3 = Examples\\Examples.csproj SccProjectUniqueName3 = Examples\\Examples.csproj
SccProjectName3 = Examples SccProjectName3 = Examples
SccLocalPath3 = Examples SccLocalPath3 = Examples
SccProjectUniqueName4 = ConsoleApplication4\\ConsoleApplication4.csproj
SccProjectName4 = ConsoleApplication4
SccLocalPath4 = ConsoleApplication4
EndGlobalSection EndGlobalSection
GlobalSection(TestCaseManagementSettings) = postSolution GlobalSection(TestCaseManagementSettings) = postSolution
CategoryFile = DocX.vsmdi CategoryFile = DocX.vsmdi

+ 16
- 3
DocX/Hyperlink.cs Просмотреть файл

internal int type; internal int type;
internal String id; internal String id;
internal XElement instrText; internal XElement instrText;
internal List<XElement> runs;
/// <summary> /// <summary>
/// Remove a Hyperlink from this Paragraph only. /// Remove a Hyperlink from this Paragraph only.
else else
{ {
Xml.ReplaceWith(newRuns);
XElement separate = XElement.Parse(@"
<w:r xmlns:w='http://schemas.openxmlformats.org/wordprocessingml/2006/main'>
<w:fldChar w:fldCharType='separate'/>
</w:r>");
XElement end = XElement.Parse(@"
<w:r xmlns:w='http://schemas.openxmlformats.org/wordprocessingml/2006/main'>
<w:fldChar w:fldCharType='end' />
</w:r>");
runs.Last().AddAfterSelf(separate, newRuns, end);
runs.ForEach(r => r.Remove());
} }
this.text = value; this.text = value;
this.text = sb.ToString(); this.text = sb.ToString();
} }
internal Hyperlink(DocX document, XElement instrText, XElement r) : base(document, r)
internal Hyperlink(DocX document, XElement instrText, List<XElement> runs) : base(document, null)
{ {
this.type = 1; this.type = 1;
this.instrText = instrText; this.instrText = instrText;
this.runs = runs;
try try
{ {
this.uri = new Uri(instrText.Value.Substring(start, end - start), UriKind.Absolute); this.uri = new Uri(instrText.Value.Substring(start, end - start), UriKind.Absolute);
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
HelperFunctions.GetTextRecursive(r, ref sb);
HelperFunctions.GetTextRecursive(new XElement(XName.Get("temp", DocX.w.NamespaceName), runs), ref sb);
this.text = sb.ToString(); this.text = sb.ToString();
} }
} }

+ 58
- 6
DocX/Paragraph.cs Просмотреть файл

while (e.Name.LocalName != "r") while (e.Name.LocalName != "r")
e = e.Parent; e = e.Parent;
// Take every element until we reach w:fldCharType="end"
List<XElement> hyperlink_runs = new List<XElement>();
foreach (XElement r in e.ElementsAfterSelf(XName.Get("r", DocX.w.NamespaceName))) foreach (XElement r in e.ElementsAfterSelf(XName.Get("r", DocX.w.NamespaceName)))
{ {
XElement rStyle = r.Descendants(XName.Get("rStyle", DocX.w.NamespaceName)).SingleOrDefault<XElement>();
if (rStyle != null)
// Add this run to the list.
hyperlink_runs.Add(r);
XElement fldChar = r.Descendants(XName.Get("fldChar", DocX.w.NamespaceName)).SingleOrDefault<XElement>();
if (fldChar != null)
{ {
XAttribute a = rStyle.Attribute(XName.Get("val", DocX.w.NamespaceName));
if (a != null && a.Value.Equals("Hyperlink", StringComparison.CurrentCultureIgnoreCase))
XAttribute fldCharType = fldChar.Attribute(XName.Get("fldCharType", DocX.w.NamespaceName));
if (fldCharType != null && fldCharType.Value.Equals("end", StringComparison.CurrentCultureIgnoreCase))
{ {
try try
{ {
Hyperlink h = new Hyperlink(Document, he, r);
Hyperlink h = new Hyperlink(Document, he, hyperlink_runs);
h.mainPart = mainPart; h.mainPart = mainPart;
hyperlinks.Add(h); hyperlinks.Add(h);
} }
catch(Exception){} catch(Exception){}
break;
} }
} }
} }
return this; return this;
} }
/// <summary>
/// Append a field of type document property, this field will display the custom property cp, at the end of this paragraph.
/// </summary>
/// <param name="cp">The custom property to display.</param>
/// <param name="f">The formatting to use for this text.</param>
/// <example>
/// Create, add and display a custom property in a document.
/// <code>
///// Load a document.
///using (DocX document = DocX.Create("CustomProperty_Add.docx"))
///{
/// // Add a few Custom Properties to this document.
/// document.AddCustomProperty(new CustomProperty("fname", "cathal"));
/// document.AddCustomProperty(new CustomProperty("age", 24));
/// document.AddCustomProperty(new CustomProperty("male", true));
/// document.AddCustomProperty(new CustomProperty("newyear2012", new DateTime(2012, 1, 1)));
/// document.AddCustomProperty(new CustomProperty("fav_num", 3.141592));
///
/// // Insert a new Paragraph and append a load of DocProperties.
/// Paragraph p = document.InsertParagraph("fname: ")
/// .AppendDocProperty(document.CustomProperties["fname"])
/// .Append(", age: ")
/// .AppendDocProperty(document.CustomProperties["age"])
/// .Append(", male: ")
/// .AppendDocProperty(document.CustomProperties["male"])
/// .Append(", newyear2012: ")
/// .AppendDocProperty(document.CustomProperties["newyear2012"])
/// .Append(", fav_num: ")
/// .AppendDocProperty(document.CustomProperties["fav_num"]);
///
/// // Save the changes to the document.
/// document.Save();
///}
/// </code>
/// </example>
public Paragraph AppendDocProperty(CustomProperty cp, bool trackChanges = false, Formatting f = null)
{
this.InsertDocProperty(cp, trackChanges, f);
return this;
}
/// <summary> /// <summary>
/// Insert a field of type document property, this field will display the custom property cp, at the end of this paragraph. /// Insert a field of type document property, this field will display the custom property cp, at the end of this paragraph.
/// </summary> /// </summary>
/// </example> /// </example>
public DocProperty InsertDocProperty(CustomProperty cp, bool trackChanges = false, Formatting f = null) public DocProperty InsertDocProperty(CustomProperty cp, bool trackChanges = false, Formatting f = null)
{ {
XElement f_xml = null;
if (f != null)
f_xml = f.Xml;
XElement e = new XElement XElement e = new XElement
( (
XName.Get("fldSimple", DocX.w.NamespaceName), XName.Get("fldSimple", DocX.w.NamespaceName),
new XAttribute(XName.Get("instr", DocX.w.NamespaceName), string.Format(@"DOCPROPERTY {0} \* MERGEFORMAT", cp.Name)), new XAttribute(XName.Get("instr", DocX.w.NamespaceName), string.Format(@"DOCPROPERTY {0} \* MERGEFORMAT", cp.Name)),
new XElement(XName.Get("r", DocX.w.NamespaceName), new XElement(XName.Get("r", DocX.w.NamespaceName),
new XElement(XName.Get("t", DocX.w.NamespaceName), f.Xml, cp.Value))
new XElement(XName.Get("t", DocX.w.NamespaceName), f_xml, cp.Value))
); );
XElement xml = e; XElement xml = e;

+ 40
- 0
UnitTests/UnitTest1.cs Просмотреть файл

} }
[TestMethod]
public void Test_CustomProperty_Add()
{
// Load a document.
using (DocX document = DocX.Create("CustomProperty_Add.docx"))
{
Assert.IsTrue(document.CustomProperties.Count == 0);
document.AddCustomProperty(new CustomProperty("fname", "cathal"));
Assert.IsTrue(document.CustomProperties.Count == 1);
Assert.IsTrue(document.CustomProperties.ContainsKey("fname"));
Assert.IsTrue((String)document.CustomProperties["fname"].Value == "cathal");
document.AddCustomProperty(new CustomProperty("age", 24));
Assert.IsTrue(document.CustomProperties.Count == 2);
Assert.IsTrue(document.CustomProperties.ContainsKey("age"));
Assert.IsTrue((int)document.CustomProperties["age"].Value == 24);
document.AddCustomProperty(new CustomProperty("male", true));
Assert.IsTrue(document.CustomProperties.Count == 3);
Assert.IsTrue(document.CustomProperties.ContainsKey("male"));
Assert.IsTrue((bool)document.CustomProperties["male"].Value == true);
document.AddCustomProperty(new CustomProperty("newyear2012", new DateTime(2012, 1, 1)));
Assert.IsTrue(document.CustomProperties.Count == 4);
Assert.IsTrue(document.CustomProperties.ContainsKey("newyear2012"));
Assert.IsTrue((DateTime)document.CustomProperties["newyear2012"].Value == new DateTime(2012, 1, 1));
document.AddCustomProperty(new CustomProperty("fav_num", 3.141592));
Assert.IsTrue(document.CustomProperties.Count == 5);
Assert.IsTrue(document.CustomProperties.ContainsKey("fav_num"));
Assert.IsTrue((double)document.CustomProperties["fav_num"].Value == 3.141592);
}
}
[TestMethod] [TestMethod]
public void Test_EverybodyHasAHome_Loaded() public void Test_EverybodyHasAHome_Loaded()
{ {

Загрузка…
Отмена
Сохранить