Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions OpenXmlFormats/Wordprocessing/Paragraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1229,6 +1229,11 @@ public bool IsSetSectPr()
{
return this.sectPr != null;
}

public void UnsetJc()
{
this.jc=null;
}
}


Expand Down
81 changes: 60 additions & 21 deletions ooxml/XWPF/Usermodel/XWPFParagraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -569,18 +569,27 @@ public String FootnoteText
/// <summary>
/// Returns the paragraph alignment which shall be applied to text in this paragraph.
/// </summary>
public ParagraphAlignment Alignment
public ParagraphAlignment? Alignment
{
get
{
CT_PPr pr = GetCTPPr();
return pr == null || !pr.IsSetJc() ? ParagraphAlignment.LEFT : EnumConverter.ValueOf<ParagraphAlignment, ST_Jc>(pr.jc.val);
CT_PPr pr = GetCTPPr(false);
return (pr == null || !pr.IsSetJc()) ? ParagraphAlignment.LEFT : EnumConverter.ValueOf<ParagraphAlignment, ST_Jc>(pr.jc.val);
}
set
{
CT_PPr pr = GetCTPPr();
CT_Jc jc = pr.IsSetJc() ? pr.jc : pr.AddNewJc();
jc.val = EnumConverter.ValueOf<ST_Jc, ParagraphAlignment>(value);
if(value==null)
{
CT_PPr pr = GetCTPPr(false);
if(pr!=null)
pr.UnsetJc();
}
else
{
CT_PPr pr = GetCTPPr(true);
CT_Jc jc = pr.IsSetJc() ? pr.jc : pr.AddNewJc();
jc.val = EnumConverter.ValueOf<ST_Jc, ParagraphAlignment>((ParagraphAlignment) value);
}
}
}

Expand Down Expand Up @@ -621,7 +630,7 @@ public TextAlignment VerticalAlignment
{
get
{
CT_PPr pr = GetCTPPr();
CT_PPr pr = GetCTPPr(false);
return (pr == null || !pr.IsSetTextAlignment()) ? TextAlignment.AUTO
: EnumConverter.ValueOf<TextAlignment, ST_TextAlignment>(pr.textAlignment.val);
}
Expand Down Expand Up @@ -1242,8 +1251,8 @@ public bool IsWordWrapped
{
get
{
CT_OnOff wordWrap = GetCTPPr().IsSetWordWrap() ? GetCTPPr()
.wordWrap : null;
var ppr = GetCTPPr(false);
CT_OnOff wordWrap = ppr!=null && ppr.IsSetWordWrap() ? ppr.wordWrap : null;
if (wordWrap != null)
{
return wordWrap.val;
Expand Down Expand Up @@ -1274,15 +1283,28 @@ public String Style
{
get
{
CT_PPr pr = GetCTPPr();
CT_PPr pr = GetCTPPr(false);
if(pr==null)
{
return null;
}
CT_String style = pr.IsSetPStyle() ? pr.pStyle : null;
return style != null ? style.val : null;
}
set
{
CT_PPr pr = GetCTPPr();
CT_String style = pr.pStyle != null ? pr.pStyle : pr.AddNewPStyle();
style.val = value;
if(value==null)
{
var pr= GetCTPPr(false);
if(pr!=null)
pr.jc = null;
}
else
{
CT_PPr pr = GetCTPPr(true);
CT_String style = pr.pStyle != null ? pr.pStyle : pr.AddNewPStyle();
style.val = value;
}
}
}

Expand All @@ -1292,12 +1314,15 @@ public String Style
*/
private CT_PBdr GetCTPBrd(bool create)
{
CT_PPr pr = GetCTPPr();
CT_PPr pr = GetCTPPr(create);
if(pr==null)
{
return null;
}
CT_PBdr ct = pr.IsSetPBdr() ? pr.pBdr : null;
if (create && ct == null)
if(create && ct == null)
ct = pr.AddNewPBdr();
return ct;

}

/**
Expand All @@ -1306,7 +1331,7 @@ private CT_PBdr GetCTPBrd(bool create)
*/
private CT_Spacing GetCTSpacing(bool create)
{
CT_PPr pr = GetCTPPr();
CT_PPr pr = GetCTPPr(create);
CT_Spacing ct = pr.spacing == null ? null : pr.spacing;
if (create && ct == null)
ct = pr.AddNewSpacing();
Expand All @@ -1319,20 +1344,23 @@ private CT_Spacing GetCTSpacing(bool create)
*/
private CT_Ind GetCTInd(bool create)
{
CT_PPr pr = GetCTPPr();
CT_PPr pr = GetCTPPr(create);
CT_Ind ct = pr.ind == null ? null : pr.ind;
if (create && ct == null)
ct = pr.AddNewInd();
return ct;
}

internal CT_PPr GetCTPPr()
{
return GetCTPPr(true);
}
/**
* Get a <b>copy</b> of the currently used CTPPr, if none is used, return
* a new instance.
*/
internal CT_PPr GetCTPPr()
internal CT_PPr GetCTPPr(bool create)
{
CT_PPr pr = paragraph.pPr == null ? paragraph.AddNewPPr()
CT_PPr pr = (paragraph.pPr == null||!create) ? paragraph.AddNewPPr()
: paragraph.pPr;
return pr;
}
Expand Down Expand Up @@ -1862,6 +1890,17 @@ private bool IsTheOnlyCTFieldInRuns(XWPFFieldRun run)
&& ctField == ((XWPFFieldRun) r).GetCTField());
return count <= 1;
}

/// <summary>
/// Returns true if the paragraph has a paragraph alignment value of its own
/// or false in case it should fall back to the alignment value set by the paragraph style.
/// </summary>
/// <returns></returns>
public bool IsAlignmentSet()
{
var pr = GetCTPPr(false);
return pr != null && pr.IsSetJc();
}
}

}
15 changes: 15 additions & 0 deletions testcases/ooxml/XWPF/TestXWPFBugs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ namespace TestCases.XWPF
using NUnit.Framework;using NUnit.Framework.Legacy;
using System;
using System.IO;
using System.Reflection.Metadata;
using System.Xml;
using TestCases;

Expand Down Expand Up @@ -287,6 +288,20 @@ private static void addNumberingWithAbstractId(XWPFNumbering documentNumbering,

documentNumbering.AddNum(abstractNumID);
}

[Test]
public void CorrectParagraphAlignment()
{
using (var document = XWPFTestDataSamples.OpenSampleDocument("bug-paragraph-alignment.docx")) {
XWPFParagraph centeredParagraph = document.GetParagraphArray(0);
ClassicAssert.IsFalse(centeredParagraph.IsAlignmentSet());
ClassicAssert.AreEqual(ParagraphAlignment.LEFT, centeredParagraph.Alignment); // LEFT is a fallback value here.

XWPFParagraph leftParagraph = document.GetParagraphArray(1);
ClassicAssert.IsTrue(leftParagraph.IsAlignmentSet());
ClassicAssert.AreEqual(ParagraphAlignment.LEFT, leftParagraph.Alignment); // LEFT is the real alignment value.
}
}
}
}

31 changes: 20 additions & 11 deletions testcases/ooxml/XWPF/UserModel/TestXWPFParagraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,23 +105,32 @@ public void TestSetBorderTop()
}

[Test]
public void TestSetAlignment()
public void TestSetGetAlignment()
{
//new clean instance of paragraph
XWPFDocument doc = new XWPFDocument();
XWPFParagraph p = doc.CreateParagraph();
using(XWPFDocument doc = new XWPFDocument())
{
XWPFParagraph p = doc.CreateParagraph();

ClassicAssert.AreEqual(ParagraphAlignment.LEFT, p.Alignment);
ClassicAssert.AreEqual(ParagraphAlignment.LEFT, p.Alignment);
ClassicAssert.IsFalse(p.IsAlignmentSet());

CT_P ctp = p.GetCTP();
CT_PPr ppr = ctp.pPr == null ? ctp.AddNewPPr() : ctp.pPr;
CT_P ctp = p.GetCTP();
CT_PPr ppr = ctp.pPr == null ? ctp.AddNewPPr() : ctp.pPr;

CT_Jc align = ppr.AddNewJc();
align.val = (ST_Jc.center);
ClassicAssert.AreEqual(ParagraphAlignment.CENTER, p.Alignment);
CT_Jc align = ppr.AddNewJc();
align.val = (ST_Jc.center);
ClassicAssert.AreEqual(ParagraphAlignment.CENTER, p.Alignment);
ClassicAssert.IsTrue(p.IsAlignmentSet());

p.Alignment = (ParagraphAlignment.BOTH);
ClassicAssert.AreEqual((int)ST_Jc.both, (int)ppr.jc.val);
p.Alignment = (ParagraphAlignment.BOTH);
ClassicAssert.AreEqual((int) ST_Jc.both, (int) ppr.jc.val);
ClassicAssert.IsTrue(p.IsAlignmentSet());

p.Alignment=null;
ClassicAssert.AreEqual(ParagraphAlignment.LEFT, p.Alignment);
ClassicAssert.IsFalse(p.IsAlignmentSet());
}
}

[Test]
Expand Down
Binary file not shown.
Loading