Skip to content

Commit

Permalink
New method NumberingDefinitionsPart resolveLinkedAbstractNum which up…
Browse files Browse the repository at this point in the history
…dates abstract list definitions which have w:numStyleLink
  • Loading branch information
plutext committed Aug 28, 2013
1 parent 1ca9af4 commit 26ca4f1
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 47 deletions.
Expand Up @@ -61,9 +61,9 @@ public abstract class AbstractWmlConversionContext extends AbstractConversionCon
protected StyleTree styleTree = null;


protected AbstractWmlConversionContext(AbstractWriterRegistry modelRegistry, AbstractMessageWriter messageWriter, AbstractConversionSettings conversionSettings, WordprocessingMLPackage wmlPackage, ConversionSectionWrappers conversionSectionWrappers) {
protected AbstractWmlConversionContext(AbstractWriterRegistry writerRegistry, AbstractMessageWriter messageWriter, AbstractConversionSettings conversionSettings, WordprocessingMLPackage wmlPackage, ConversionSectionWrappers conversionSectionWrappers) {
super(messageWriter, conversionSettings, wmlPackage);
this.writerRegistry = initializeModelRegistry(modelRegistry);
this.writerRegistry = initializeWriterRegistry(writerRegistry);
this.transformStates = initializeTransformStates();
this.conversionSectionWrappers = conversionSectionWrappers;
this.styleTree = initializeStyleTree();
Expand All @@ -75,16 +75,27 @@ protected OpcPackage initializeOpcPackage(AbstractConversionSettings conversionS
if (!(ret instanceof WordprocessingMLPackage)) {
throw new IllegalArgumentException("The opcPackage isn't a WordprocessingMLPackage, it is a " + ret.getClass().getName());
}
resolveLinkedAbstractNum((WordprocessingMLPackage)ret);
return ret;
}

protected AbstractWriterRegistry initializeModelRegistry(AbstractWriterRegistry registry) {
protected AbstractWriterRegistry initializeWriterRegistry(AbstractWriterRegistry registry) {
return registry;
}

protected Map<String, Writer.TransformState> initializeTransformStates() {
return getWriterRegistry().createTransformStates();
}

protected void resolveLinkedAbstractNum(WordprocessingMLPackage wmlPkg) {

if (wmlPkg.getMainDocumentPart().getStyleDefinitionsPart()!=null
&& wmlPkg.getMainDocumentPart().getNumberingDefinitionsPart()!=null) {

wmlPkg.getMainDocumentPart().getNumberingDefinitionsPart().resolveLinkedAbstractNum(
wmlPkg.getMainDocumentPart().getStyleDefinitionsPart());
}
}

protected StyleTree initializeStyleTree() {
//catching and swallowing an exception here isn't good,
Expand Down
Expand Up @@ -163,7 +163,7 @@ public AbstractListNumberingDefinition(Numbering.AbstractNum abstractNumNode)
this.readListLevelsFromAbsNode(abstractNumNode);

// find out whether there is a linked abstractNum definition that this needs to be populated from later on
//XmlNode linkedStyleNode = abstractNumNode.SelectSingleNode("./w:numStyleLink", nsm);
// NDP.resolveLinkedAbstractNum
Numbering.AbstractNum.NumStyleLink linkedStyleNode = abstractNumNode.getNumStyleLink();

if (linkedStyleNode != null)
Expand All @@ -173,19 +173,8 @@ public AbstractListNumberingDefinition(Numbering.AbstractNum abstractNumNode)
}
}

/// <summary>
/// update the level definitions from a linked abstractNum node
/// </summary>
/// <param name="linkedNode">
/// </param>
/// <param name="nsm">
/// </param>
/// <id guid="36473168-7947-41ea-8210-839bf07eded7" />
/// <owner alias="ROrleth" />
public void UpdateDefinitionFromLinkedStyle(Numbering.AbstractNum linkedNode)
public void updateDefinitionFromLinkedStyle(Numbering.AbstractNum linkedNode)
{
// TODO - review this; it looks wrong!

if (!this.hasLinkedStyle() )
return;

Expand Down Expand Up @@ -215,30 +204,17 @@ private void readListLevelsFromAbsNode(Numbering.AbstractNum abstractNumNode)
}

private String linkedStyleId;

/// <summary>
/// returnts the ID of the linked style
/// </summary>
/// <id guid="ae2caeec-2d86-4e5f-b816-d508f6f2c893" />
/// <owner alias="ROrleth" />
public String getLinkedStyleId()
{
return this.linkedStyleId;
public String getLinkedStyleId() {
return this.linkedStyleId;
}

/// <summary>
/// indicates whether there is a linked style
/// </summary>
/// <id guid="75d74788-9839-448e-ae23-02d40e013d98" />
/// <owner alias="ROrleth" />
public boolean hasLinkedStyle()
{
if (this.linkedStyleId!=null && !this.linkedStyleId.equals("") ) {
return true;
} else {
return false;
}
//return !String.IsNullOrEmpty(this.linkedStyleId);
}


Expand Down
Expand Up @@ -145,7 +145,29 @@ public ListNumberingDefinition(Numbering.Num numNode,
} else {
this.abstractListDefinition = abstractListDefinitions.get(abstractNumNode.getVal().toString() ); //[getAttributeValue(abstractNumNode, ValAttrName)];
if (abstractListDefinition==null) {
log.warn("No abstractListDefinition for w:numId=" + listNumberId);
log.warn("No abstractListDefinition for w:numId=" + listNumberId);
return;
}
if (this.abstractListDefinition.getLevelCount()==0
&& this.abstractListDefinition.hasLinkedStyle()) {

/* Something like:
*
<w:abstractNum w:abstractNumId="0">
<w:nsid w:val="42FF6222"/>
<w:multiLevelType w:val="multilevel"/>
<w:tmpl w:val="0409001D"/>
<w:numStyleLink w:val="MyListStyle"/>
</w:abstractNum>
*
* We need to go back to the style, which will point to a concrete numId
* which will in turn point to some *other* abstractNum!
* Why M$ designed things this way defies logic!
*
* This is done when NDP.resolveLinkedAbstractNum is invoked,
* typically by AbstractWmlConversionContext, prior to converting
* the docx to HTML or PDF.
*/
}

this.levels = new HashMap<String, ListLevel>(this.abstractListDefinition.getLevelCount() );
Expand Down
Expand Up @@ -61,6 +61,7 @@
import org.docx4j.wml.PPrBase.NumPr;
import org.docx4j.wml.PPrBase.NumPr.Ilvl;
import org.docx4j.wml.PPrBase.NumPr.NumId;
import org.docx4j.wml.Style;



Expand Down Expand Up @@ -128,21 +129,6 @@ public void initialiseMaps()

abstractListDefinitions.put(absNumDef.getID(), absNumDef);

// now go through the abstract list definitions and update those that are linked to other styles
if (absNumDef.hasLinkedStyle() )
{
// String linkStyleXPath = "/w:document/w:numbering/w:abstractNum/w:styleLink[@w:val=\"" + absNumDef.Value.LinkedStyleId + "\"]";
// XmlNode linkedStyleNode = mainDoc.SelectSingleNode(linkStyleXPath, nsm);
//
// if (linkedStyleNode != null)
// {
// absNumDef.Value.UpdateDefinitionFromLinkedStyle(linkedStyleNode.ParentNode, nsm);
// }

// find the linked style
// TODO - review
absNumDef.UpdateDefinitionFromLinkedStyle(abstractNumNode);
}
}

// instantiate the list number definitions
Expand All @@ -157,6 +143,71 @@ public void initialiseMaps()

}

public void resolveLinkedAbstractNum(StyleDefinitionsPart sdp) {

if (sdp==null) {
log.warn("No StyleDefinitionsPart found");
return;
}

for (Numbering.AbstractNum abstractNum : getJaxbElement().getAbstractNum() ) {

// <w:numStyleLink w:val="MyListStyle"/>
if (abstractNum.getNumStyleLink()==null) continue;

// there is also abstractNum.getStyleLink(), but ignore that

String numStyleId = abstractNum.getNumStyleLink().getVal();

Style s = sdp.getStyleById(numStyleId);
if (s==null) {
log.warn("For w:numStyleLink, couldn't find style " + numStyleId);
continue;
}
if (s.getPPr()==null || s.getPPr().getNumPr()==null) {
log.warn("For w:numStyleLink, style " + numStyleId + " has no w:numPr");
continue;
}

NumPr styleNumPr = s.getPPr().getNumPr();

// Get the concrete list this point to
if (styleNumPr.getNumId()==null) {
log.warn("For w:numStyleLink, style " + numStyleId + " w:numPr has no w:numId");
continue;
}
BigInteger concreteListId = styleNumPr.getNumId().getVal();

// Get the target abstract num
ListNumberingDefinition lnd = getInstanceListDefinitions().get(concreteListId.toString());
if (lnd==null) {
log.warn("No ListNumberingDefinition entry with ID " + concreteListId.toString());
}
Numbering.AbstractNum linkedNum = lnd.getAbstractListDefinition().getAbstractNumNode();

// OK, update
AbstractListNumberingDefinition absNumDef
= abstractListDefinitions.get(abstractNum.getAbstractNumId().toString());

absNumDef.updateDefinitionFromLinkedStyle(linkedNum);

// Also update the underlying abstract list
if (abstractNum.getLvl().size()>0) {
log.warn("Cowardly refusing to overwrite existing List<Lvl>" );
} else {
abstractNum.getLvl().clear();
abstractNum.getLvl().addAll(linkedNum.getLvl());
// This list is treated as a separate list by Word (ie its numbers are incremented
// independently), and this code honours that.
}


log.info("Updated abstract list def " + abstractNum.getAbstractNumId().toString() + " based on w:numStyleLink " + numStyleId );
}


}

/**
* For the given list numId, restart the numbering on the specified
* level at value val. This is done by creating a new list (ie <w:num>)
Expand Down

0 comments on commit 26ca4f1

Please sign in to comment.