/*
* Copyright 2013, Plutext Pty Ltd.
*
* This file is part of the Commercial Edition of docx4j,
* which is licensed under the Plutext Commercial License (the "License");
* you may not use this file except in compliance with the License.
*
* In particular, this source code is CONFIDENTIAL, and you must ensure it
* stays that way.
*
* You may obtain a copy of the License at
*
* http://www.plutext.com/license/Plutext_Commercial_License.pdf
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.docx4j.toc.switches;
import java.util.HashMap;
import java.util.Map;
import org.docx4j.model.PropertyResolver;
import org.docx4j.toc.TocEntry;
import org.docx4j.toc.TocHelper;
import org.docx4j.wml.PPr;
import org.docx4j.wml.Style;
import org.docx4j.wml.PPrBase.OutlineLvl;
/**
* This switch indicates to consider the outline level set
* on the paragraph.
*
* That value trumps heading style (eg if outline level is set to
* body text, a heading won't appear in the outline),
* EXCEPT where the outline level is set in the heading style definition
* (which is ignored - the style name is parsed for the level!).
*
* If style X is based on heading style, and style X has an outline level
* setting, that setting is considered.
*
*/
public class USwitch extends AbstractSwitch {
public static final String ID = "\\u";
private static final int PRIORITY = 8;
private Map<String, OutlineLvl> knownOutlineLevels = new HashMap<String, OutlineLvl>(); // per docx
private static OutlineLvl LEVEL_9 = new OutlineLvl();
@Override
public boolean hasFieldArgument() {
return false;
}
@Override
public void process(Style s, SwitchProcessor sp) {
// Not used
}
public void process(Style s, SwitchProcessor sp, PPr pPr, OSwitch oSwitch) {
// TODO, need actual pPr, since it could have an outline level defined on it!
int cutOff=9;
if (oSwitch!=null && oSwitch.fieldArgument!=null) {
cutOff=oSwitch.getEndLevel();
}
int level = getOutlineLvl(pPr, sp, s, cutOff);
if( level == 9){
sp.proceed(false);
} else {
TocEntry te = sp.getEntry(); // creates it
te.setEntryLevel(level);
sp.setStyleFound(true);
}
}
@Override
public int getPriority() {
return PRIORITY;
}
public int getOutlineLvl(PPr pPr, SwitchProcessor sp, Style s, int cutOff) {
// Heading 1 is lvl 0
// There are 9 levels, so 9 will be lvl 8
// So return 9 for normal text
OutlineLvl outlineLvl = null;
if (pPr!=null) {
outlineLvl = pPr.getOutlineLvl();
}
// If not direct, look in styles
if (outlineLvl==null) {
if (s == null) return 9;
// Special case: a Heading style outside the range in the o switch
// is never included. That is suppose this is H3, and
// we have \o "1-2".
// if (s.getStyleId().startsWith("Heading")) {
int hLevel = sp.styleBasedOnHelper.getBasedOnHeading(s);
if (hLevel>cutOff) {
return 9;
}
// }
outlineLvl = knownOutlineLevels.get(s.getStyleId());
if (outlineLvl==null) {
PPr effectivePPr = sp.propertyResolver.getEffectivePPr(s.getStyleId());
// that takes care of any unexpected outline level found in a heading style,
// by overwriting it (see fillPPrStack)
outlineLvl = effectivePPr.getOutlineLvl();
if (outlineLvl==null) {
outlineLvl = LEVEL_9;
}
knownOutlineLevels.put(s.getStyleId(), outlineLvl);
}
}
if (outlineLvl == null // shouldn't happen
|| outlineLvl.getVal()==null // eg LEVEL_9
) return 9;
return outlineLvl.getVal().intValue();
}
}