| /* ==================================================================== |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| 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.apache.poi.hslf.usermodel; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.apache.poi.hslf.exceptions.HSLFException; |
| import org.apache.poi.hslf.model.textproperties.TextProp; |
| import org.apache.poi.hslf.model.textproperties.TextPropCollection; |
| import org.apache.poi.hslf.record.MainMaster; |
| import org.apache.poi.hslf.record.TextHeaderAtom; |
| import org.apache.poi.hslf.record.TxMasterStyleAtom; |
| import org.apache.poi.sl.usermodel.TextShape.TextPlaceholder; |
| import org.apache.poi.util.Internal; |
| |
| /** |
| * SlideMaster determines the graphics, layout, and formatting for all the slides in a given presentation. |
| * It stores information about default font styles, placeholder sizes and positions, |
| * background design, and color schemes. |
| */ |
| public final class HSLFSlideMaster extends HSLFMasterSheet { |
| private final List<List<HSLFTextParagraph>> _paragraphs = new ArrayList<>(); |
| |
| /** |
| * all TxMasterStyleAtoms available in this master |
| */ |
| private TxMasterStyleAtom[] _txmaster; |
| |
| /** |
| * Constructs a SlideMaster from the MainMaster record, |
| * |
| */ |
| public HSLFSlideMaster(MainMaster record, int sheetNo) { |
| super(record, sheetNo); |
| |
| for (List<HSLFTextParagraph> l : HSLFTextParagraph.findTextParagraphs(getPPDrawing(), this)) { |
| if (!_paragraphs.contains(l)) { |
| _paragraphs.add(l); |
| } |
| } |
| } |
| |
| /** |
| * Returns an array of all the TextRuns found |
| */ |
| @Override |
| public List<List<HSLFTextParagraph>> getTextParagraphs() { |
| return _paragraphs; |
| } |
| |
| /** |
| * Returns <code>null</code> since SlideMasters doen't have master sheet. |
| */ |
| @Override |
| public HSLFMasterSheet getMasterSheet() { |
| return null; |
| } |
| |
| /** |
| * Find the master collection for the given txtype/level/name. |
| * This is the "workhorse" which returns the default style attributes. |
| * If {@code name = "*"} return the current collection, otherwise if the name is not found |
| * in the current selection of txtype/level/name, first try lower levels then try parent types, |
| * if it wasn't found there return {@code null}. |
| * |
| * @param txtype the {@link TextHeaderAtom} type |
| * @param level the indent level of the paragraph, if the level is not defined for the found |
| * collection, the highest existing level will be used |
| * @param name the property name, |
| * @param isCharacter if {@code true} use character styles, otherwise use paragraph styles |
| */ |
| @Override |
| public TextPropCollection getPropCollection(final int txtype, final int level, final String name, final boolean isCharacter) { |
| TextPropCollection tpc = getPropHelper(txtype, level, name, isCharacter); |
| if (tpc != null) { |
| return tpc; |
| } |
| |
| TextPlaceholder tp = TextPlaceholder.fromNativeId(txtype); |
| switch (tp == null ? TextPlaceholder.BODY : tp) { |
| case BODY: |
| case CENTER_BODY: |
| case HALF_BODY: |
| case QUARTER_BODY: |
| return getPropHelper(TextPlaceholder.BODY.nativeId, level, name, isCharacter); |
| case TITLE: |
| case CENTER_TITLE: |
| return getPropHelper(TextPlaceholder.TITLE.nativeId, level, name, isCharacter); |
| default: |
| return null; |
| } |
| } |
| |
| private TextPropCollection getPropHelper(final int txtype, final int level, final String name, final boolean isCharacter) { |
| if (txtype >= _txmaster.length) { |
| return null; |
| } |
| final TxMasterStyleAtom t = _txmaster[txtype]; |
| final List<TextPropCollection> styles = isCharacter ? t.getCharacterStyles() : t.getParagraphStyles(); |
| // TODO: what is the reaction for readOnly=false and styles.isEmpty()? |
| final int minLevel = Math.min(level, styles.size()-1); |
| if ("*".equals(name)) { |
| return styles.get(minLevel); |
| } |
| |
| for (int i=minLevel; i >= 0; i--) { |
| final TextPropCollection col = styles.get(i); |
| final TextProp tp = col.findByName(name); |
| if (tp != null) { |
| return col; |
| } |
| } |
| |
| return null; |
| } |
| |
| |
| /** |
| * Assign SlideShow for this slide master. |
| */ |
| @Internal |
| @Override |
| protected void setSlideShow(HSLFSlideShow ss) { |
| super.setSlideShow(ss); |
| |
| //after the slide show is assigned collect all available style records |
| assert (_txmaster == null); |
| _txmaster = new TxMasterStyleAtom[9]; |
| |
| TxMasterStyleAtom txdoc = getSlideShow().getDocumentRecord().getEnvironment().getTxMasterStyleAtom(); |
| _txmaster[txdoc.getTextType()] = txdoc; |
| |
| TxMasterStyleAtom[] txrec = ((MainMaster)getSheetContainer()).getTxMasterStyleAtoms(); |
| for (int i = 0; i < txrec.length; i++) { |
| int txType = txrec[i].getTextType(); |
| if (txType < _txmaster.length && _txmaster[txType] == null) { |
| _txmaster[txType] = txrec[i]; |
| } |
| } |
| |
| for (List<HSLFTextParagraph> paras : getTextParagraphs()) { |
| for (HSLFTextParagraph htp : paras) { |
| int txType = htp.getRunType(); |
| if (txType >= _txmaster.length || _txmaster[txType] == null) { |
| throw new HSLFException("Master styles not initialized"); |
| } |
| |
| int level = htp.getIndentLevel(); |
| |
| List<TextPropCollection> charStyles = _txmaster[txType].getCharacterStyles(); |
| List<TextPropCollection> paragraphStyles = _txmaster[txType].getParagraphStyles(); |
| if (charStyles == null || paragraphStyles == null || |
| charStyles.size() <= level || paragraphStyles.size() <= level) { |
| throw new HSLFException("Master styles not initialized"); |
| } |
| } |
| } |
| } |
| |
| @Override |
| protected void onAddTextShape(HSLFTextShape shape) { |
| List<HSLFTextParagraph> runs = shape.getTextParagraphs(); |
| _paragraphs.add(runs); |
| } |
| |
| public TxMasterStyleAtom[] getTxMasterStyleAtoms(){ |
| return _txmaster; |
| } |
| } |