123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503 |
- /* ====================================================================
- 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.awt.Graphics2D;
- import java.util.ArrayList;
- import java.util.List;
-
- import org.apache.poi.ddf.EscherContainerRecord;
- import org.apache.poi.ddf.EscherDgRecord;
- import org.apache.poi.ddf.EscherDggRecord;
- import org.apache.poi.ddf.EscherSpRecord;
- import org.apache.poi.hslf.model.Comment;
- import org.apache.poi.hslf.model.HeadersFooters;
- import org.apache.poi.hslf.record.ColorSchemeAtom;
- import org.apache.poi.hslf.record.Comment2000;
- import org.apache.poi.hslf.record.EscherTextboxWrapper;
- import org.apache.poi.hslf.record.HeadersFootersContainer;
- import org.apache.poi.hslf.record.Record;
- import org.apache.poi.hslf.record.RecordContainer;
- import org.apache.poi.hslf.record.RecordTypes;
- import org.apache.poi.hslf.record.SSSlideInfoAtom;
- import org.apache.poi.hslf.record.SlideAtom;
- import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet;
- import org.apache.poi.hslf.record.StyleTextProp9Atom;
- import org.apache.poi.hslf.record.TextHeaderAtom;
- import org.apache.poi.sl.draw.DrawFactory;
- import org.apache.poi.sl.draw.Drawable;
- import org.apache.poi.sl.usermodel.Notes;
- import org.apache.poi.sl.usermodel.Placeholder;
- import org.apache.poi.sl.usermodel.ShapeType;
- import org.apache.poi.sl.usermodel.Slide;
-
- /**
- * This class represents a slide in a PowerPoint Document. It allows
- * access to the text within, and the layout. For now, it only does
- * the text side of things though
- *
- * @author Nick Burch
- * @author Yegor Kozlov
- */
-
- public final class HSLFSlide extends HSLFSheet implements Slide<HSLFShape,HSLFTextParagraph> {
- private int _slideNo;
- private SlideAtomsSet _atomSet;
- private final List<List<HSLFTextParagraph>> _paragraphs = new ArrayList<List<HSLFTextParagraph>>();
- private HSLFNotes _notes; // usermodel needs to set this
-
- /**
- * Constructs a Slide from the Slide record, and the SlideAtomsSet
- * containing the text.
- * Initializes TextRuns, to provide easier access to the text
- *
- * @param slide the Slide record we're based on
- * @param notes the Notes sheet attached to us
- * @param atomSet the SlideAtomsSet to get the text from
- */
- public HSLFSlide(org.apache.poi.hslf.record.Slide slide, HSLFNotes notes, SlideAtomsSet atomSet, int slideIdentifier, int slideNumber) {
- super(slide, slideIdentifier);
-
- _notes = notes;
- _atomSet = atomSet;
- _slideNo = slideNumber;
-
- // For the text coming in from the SlideAtomsSet:
- // Build up TextRuns from pairs of TextHeaderAtom and
- // one of TextBytesAtom or TextCharsAtom
- if (_atomSet != null && _atomSet.getSlideRecords().length > 0) {
- // Grab text from SlideListWithTexts entries
- _paragraphs.addAll(HSLFTextParagraph.findTextParagraphs(_atomSet.getSlideRecords()));
- if (_paragraphs.isEmpty()) {
- throw new RuntimeException("No text records found for slide");
- }
- } else {
- // No text on the slide, must just be pictures
- }
-
- // Grab text from slide's PPDrawing
- for (List<HSLFTextParagraph> l : HSLFTextParagraph.findTextParagraphs(getPPDrawing(), this)) {
- if (!_paragraphs.contains(l)) _paragraphs.add(l);
- }
- }
-
- /**
- * Create a new Slide instance
- * @param sheetNumber The internal number of the sheet, as used by PersistPtrHolder
- * @param slideNumber The user facing number of the sheet
- */
- public HSLFSlide(int sheetNumber, int sheetRefId, int slideNumber){
- super(new org.apache.poi.hslf.record.Slide(), sheetNumber);
- _slideNo = slideNumber;
- getSheetContainer().setSheetId(sheetRefId);
- }
-
- /**
- * Returns the Notes Sheet for this slide, or null if there isn't one
- */
- @Override
- public HSLFNotes getNotes() {
- return _notes;
- }
-
- /**
- * Sets the Notes that are associated with this. Updates the
- * references in the records to point to the new ID
- */
- @Override
- public void setNotes(Notes<HSLFShape,HSLFTextParagraph> notes) {
- if (notes != null && !(notes instanceof HSLFNotes)) {
- throw new IllegalArgumentException("notes needs to be of type HSLFNotes");
- }
- _notes = (HSLFNotes)notes;
-
- // Update the Slide Atom's ID of where to point to
- SlideAtom sa = getSlideRecord().getSlideAtom();
-
- if(_notes == null) {
- // Set to 0
- sa.setNotesID(0);
- } else {
- // Set to the value from the notes' sheet id
- sa.setNotesID(_notes._getSheetNumber());
- }
- }
-
- /**
- * Changes the Slide's (external facing) page number.
- * @see org.apache.poi.hslf.usermodel.HSLFSlideShow#reorderSlide(int, int)
- */
- public void setSlideNumber(int newSlideNumber) {
- _slideNo = newSlideNumber;
- }
-
- /**
- * Called by SlideShow ater a new slide is created.
- * <p>
- * For Slide we need to do the following:
- * <li> set id of the drawing group.
- * <li> set shapeId for the container descriptor and background
- * </p>
- */
- public void onCreate(){
- //initialize drawing group id
- EscherDggRecord dgg = getSlideShow().getDocumentRecord().getPPDrawingGroup().getEscherDggRecord();
- EscherContainerRecord dgContainer = getSheetContainer().getPPDrawing().getDgContainer();
- EscherDgRecord dg = (EscherDgRecord) HSLFShape.getEscherChild(dgContainer, EscherDgRecord.RECORD_ID);
- int dgId = dgg.getMaxDrawingGroupId() + 1;
- dg.setOptions((short)(dgId << 4));
- dgg.setDrawingsSaved(dgg.getDrawingsSaved() + 1);
- dgg.setMaxDrawingGroupId(dgId);
-
- for (EscherContainerRecord c : dgContainer.getChildContainers()) {
- EscherSpRecord spr = null;
- switch(c.getRecordId()){
- case EscherContainerRecord.SPGR_CONTAINER:
- EscherContainerRecord dc = (EscherContainerRecord)c.getChild(0);
- spr = dc.getChildById(EscherSpRecord.RECORD_ID);
- break;
- case EscherContainerRecord.SP_CONTAINER:
- spr = c.getChildById(EscherSpRecord.RECORD_ID);
- break;
- default:
- break;
- }
- if(spr != null) spr.setShapeId(allocateShapeId());
- }
-
- //PPT doen't increment the number of saved shapes for group descriptor and background
- dg.setNumShapes(1);
- }
-
- /**
- * Create a <code>TextBox</code> object that represents the slide's title.
- *
- * @return <code>TextBox</code> object that represents the slide's title.
- */
- public HSLFTextBox addTitle() {
- HSLFPlaceholder pl = new HSLFPlaceholder();
- pl.setShapeType(ShapeType.RECT);
- pl.setPlaceholder(Placeholder.TITLE);
- pl.setRunType(TextHeaderAtom.TITLE_TYPE);
- pl.setText("Click to edit title");
- pl.setAnchor(new java.awt.Rectangle(54, 48, 612, 90));
- addShape(pl);
- return pl;
- }
-
-
- // Complex Accesser methods follow
-
- /**
- * <p>
- * The title is a run of text of type <code>TextHeaderAtom.CENTER_TITLE_TYPE</code> or
- * <code>TextHeaderAtom.TITLE_TYPE</code>
- * </p>
- *
- * @see TextHeaderAtom
- */
- @Override
- public String getTitle(){
- for (List<HSLFTextParagraph> tp : getTextParagraphs()) {
- if (tp.isEmpty()) continue;
- int type = tp.get(0).getRunType();
- switch (type) {
- case TextHeaderAtom.CENTER_TITLE_TYPE:
- case TextHeaderAtom.TITLE_TYPE:
- String str = HSLFTextParagraph.getRawText(tp);
- return HSLFTextParagraph.toExternalString(str, type);
- }
- }
- return null;
- }
-
- // Simple Accesser methods follow
-
- /**
- * Returns an array of all the TextRuns found
- */
- public List<List<HSLFTextParagraph>> getTextParagraphs() { return _paragraphs; }
-
- /**
- * Returns the (public facing) page number of this slide
- */
- @Override
- public int getSlideNumber() { return _slideNo; }
-
- /**
- * Returns the underlying slide record
- */
- public org.apache.poi.hslf.record.Slide getSlideRecord() {
- return (org.apache.poi.hslf.record.Slide)getSheetContainer();
- }
-
- /**
- * @return set of records inside <code>SlideListWithtext</code> container
- * which hold text data for this slide (typically for placeholders).
- */
- protected SlideAtomsSet getSlideAtomsSet() { return _atomSet; }
-
- /**
- * Returns master sheet associated with this slide.
- * It can be either SlideMaster or TitleMaster objects.
- *
- * @return the master sheet associated with this slide.
- */
- public HSLFMasterSheet getMasterSheet(){
- int masterId = getSlideRecord().getSlideAtom().getMasterID();
- for (HSLFSlideMaster sm : getSlideShow().getSlideMasters()) {
- if (masterId == sm._getSheetNumber()) return sm;
- }
- for (HSLFTitleMaster tm : getSlideShow().getTitleMasters()) {
- if (masterId == tm._getSheetNumber()) return tm;
- }
- return null;
- }
-
- /**
- * Change Master of this slide.
- */
- public void setMasterSheet(HSLFMasterSheet master){
- SlideAtom sa = getSlideRecord().getSlideAtom();
- int sheetNo = master._getSheetNumber();
- sa.setMasterID(sheetNo);
- }
-
- /**
- * Sets whether this slide follows master background
- *
- * @param flag <code>true</code> if the slide follows master,
- * <code>false</code> otherwise
- */
- public void setFollowMasterBackground(boolean flag){
- SlideAtom sa = getSlideRecord().getSlideAtom();
- sa.setFollowMasterBackground(flag);
- }
-
- /**
- * Whether this slide follows master sheet background
- *
- * @return <code>true</code> if the slide follows master background,
- * <code>false</code> otherwise
- */
- public boolean getFollowMasterBackground(){
- SlideAtom sa = getSlideRecord().getSlideAtom();
- return sa.getFollowMasterBackground();
- }
-
- /**
- * Sets whether this slide draws master sheet objects
- *
- * @param flag <code>true</code> if the slide draws master sheet objects,
- * <code>false</code> otherwise
- */
- public void setFollowMasterObjects(boolean flag){
- SlideAtom sa = getSlideRecord().getSlideAtom();
- sa.setFollowMasterObjects(flag);
- }
-
- /**
- * Whether this slide follows master color scheme
- *
- * @return <code>true</code> if the slide follows master color scheme,
- * <code>false</code> otherwise
- */
- public boolean getFollowMasterScheme(){
- SlideAtom sa = getSlideRecord().getSlideAtom();
- return sa.getFollowMasterScheme();
- }
-
- /**
- * Sets whether this slide draws master color scheme
- *
- * @param flag <code>true</code> if the slide draws master color scheme,
- * <code>false</code> otherwise
- */
- public void setFollowMasterScheme(boolean flag){
- SlideAtom sa = getSlideRecord().getSlideAtom();
- sa.setFollowMasterScheme(flag);
- }
-
- /**
- * Whether this slide draws master sheet objects
- *
- * @return <code>true</code> if the slide draws master sheet objects,
- * <code>false</code> otherwise
- */
- public boolean getFollowMasterObjects(){
- SlideAtom sa = getSlideRecord().getSlideAtom();
- return sa.getFollowMasterObjects();
- }
-
- /**
- * Background for this slide.
- */
- public HSLFBackground getBackground() {
- if(getFollowMasterBackground()) {
- return getMasterSheet().getBackground();
- }
- return super.getBackground();
- }
-
- /**
- * Color scheme for this slide.
- */
- public ColorSchemeAtom getColorScheme() {
- if(getFollowMasterScheme()){
- return getMasterSheet().getColorScheme();
- }
- return super.getColorScheme();
- }
-
- /**
- * Get the comment(s) for this slide.
- * Note - for now, only works on PPT 2000 and
- * PPT 2003 files. Doesn't work for PPT 97
- * ones, as they do their comments oddly.
- */
- public Comment[] getComments() {
- // If there are any, they're in
- // ProgTags -> ProgBinaryTag -> BinaryTagData
- RecordContainer progTags = (RecordContainer)
- getSheetContainer().findFirstOfType(
- RecordTypes.ProgTags.typeID
- );
- if(progTags != null) {
- RecordContainer progBinaryTag = (RecordContainer)
- progTags.findFirstOfType(
- RecordTypes.ProgBinaryTag.typeID
- );
- if(progBinaryTag != null) {
- RecordContainer binaryTags = (RecordContainer)
- progBinaryTag.findFirstOfType(
- RecordTypes.BinaryTagData.typeID
- );
- if(binaryTags != null) {
- // This is where they'll be
- int count = 0;
- for(int i=0; i<binaryTags.getChildRecords().length; i++) {
- if(binaryTags.getChildRecords()[i] instanceof Comment2000) {
- count++;
- }
- }
-
- // Now build
- Comment[] comments = new Comment[count];
- count = 0;
- for(int i=0; i<binaryTags.getChildRecords().length; i++) {
- if(binaryTags.getChildRecords()[i] instanceof Comment2000) {
- comments[i] = new Comment(
- (Comment2000)binaryTags.getChildRecords()[i]
- );
- count++;
- }
- }
-
- return comments;
- }
- }
- }
-
- // None found
- return new Comment[0];
- }
-
- /**
- * Header / Footer settings for this slide.
- *
- * @return Header / Footer settings for this slide
- */
- public HeadersFooters getHeadersFooters(){
- HeadersFootersContainer hdd = null;
- Record[] ch = getSheetContainer().getChildRecords();
- boolean ppt2007 = false;
- for (int i = 0; i < ch.length; i++) {
- if(ch[i] instanceof HeadersFootersContainer){
- hdd = (HeadersFootersContainer)ch[i];
- } else if (ch[i].getRecordType() == RecordTypes.RoundTripContentMasterId.typeID){
- ppt2007 = true;
- }
- }
- boolean newRecord = false;
- if(hdd == null && !ppt2007) {
- return getSlideShow().getSlideHeadersFooters();
- }
- if(hdd == null) {
- hdd = new HeadersFootersContainer(HeadersFootersContainer.SlideHeadersFootersContainer);
- newRecord = true;
- }
- return new HeadersFooters(hdd, this, newRecord, ppt2007);
- }
-
- protected void onAddTextShape(HSLFTextShape shape) {
- List<HSLFTextParagraph> newParas = shape.getTextParagraphs();
- _paragraphs.add(newParas);
- }
-
- /** This will return an atom per TextBox, so if the page has two text boxes the method should return two atoms. */
- public StyleTextProp9Atom[] getNumberedListInfo() {
- return this.getPPDrawing().getNumberedListInfo();
- }
-
- public EscherTextboxWrapper[] getTextboxWrappers() {
- return this.getPPDrawing().getTextboxWrappers();
- }
-
- public void setHidden(boolean hidden) {
- org.apache.poi.hslf.record.Slide cont = getSlideRecord();
-
- SSSlideInfoAtom slideInfo =
- (SSSlideInfoAtom)cont.findFirstOfType(RecordTypes.SSSlideInfoAtom.typeID);
- if (slideInfo == null) {
- slideInfo = new SSSlideInfoAtom();
- cont.addChildAfter(slideInfo, cont.findFirstOfType(RecordTypes.SlideAtom.typeID));
- }
-
- slideInfo.setEffectTransitionFlagByBit(SSSlideInfoAtom.HIDDEN_BIT, hidden);
- }
-
- public boolean getHidden() {
- SSSlideInfoAtom slideInfo =
- (SSSlideInfoAtom)getSlideRecord().findFirstOfType(RecordTypes.SSSlideInfoAtom.typeID);
- return (slideInfo == null)
- ? false
- : slideInfo.getEffectTransitionFlagByBit(SSSlideInfoAtom.HIDDEN_BIT);
- }
-
- @Override
- public void draw(Graphics2D graphics) {
- DrawFactory drawFact = DrawFactory.getInstance(graphics);
- Drawable draw = drawFact.getDrawable(this);
- draw.draw(graphics);
- }
-
- public boolean getFollowMasterColourScheme() {
- // TODO Auto-generated method stub
- return false;
- }
-
- public void setFollowMasterColourScheme(boolean follow) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public boolean getFollowMasterGraphics() {
- return getFollowMasterObjects();
- }
- }
|