123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462 |
- /* ====================================================================
- 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.awt.geom.Rectangle2D;
- import java.util.ArrayList;
- import java.util.Iterator;
- 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.EscherRecord;
- import org.apache.poi.hslf.exceptions.HSLFException;
- import org.apache.poi.hslf.record.CString;
- import org.apache.poi.hslf.record.ColorSchemeAtom;
- import org.apache.poi.hslf.record.OEPlaceholderAtom;
- import org.apache.poi.hslf.record.PPDrawing;
- import org.apache.poi.hslf.record.RecordContainer;
- import org.apache.poi.hslf.record.RecordTypes;
- import org.apache.poi.hslf.record.RoundTripHFPlaceholder12;
- import org.apache.poi.hslf.record.SheetContainer;
- import org.apache.poi.sl.draw.DrawFactory;
- import org.apache.poi.sl.draw.Drawable;
- import org.apache.poi.sl.usermodel.PictureData;
- import org.apache.poi.sl.usermodel.ShapeType;
- import org.apache.poi.sl.usermodel.Sheet;
- import org.apache.poi.util.Internal;
-
- /**
- * This class defines the common format of "Sheets" in a powerpoint
- * document. Such sheets could be Slides, Notes, Master etc
- *
- * @author Nick Burch
- * @author Yegor Kozlov
- */
-
- public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,HSLFTextParagraph> {
- /**
- * The <code>SlideShow</code> we belong to
- */
- private HSLFSlideShow _slideShow;
-
- /**
- * Sheet background
- */
- private HSLFBackground _background;
-
- /**
- * Record container that holds sheet data.
- * For slides it is org.apache.poi.hslf.record.Slide,
- * for notes it is org.apache.poi.hslf.record.Notes,
- * for slide masters it is org.apache.poi.hslf.record.SlideMaster, etc.
- */
- private SheetContainer _container;
-
- private int _sheetNo;
-
- public HSLFSheet(SheetContainer container, int sheetNo) {
- _container = container;
- _sheetNo = sheetNo;
- }
-
- /**
- * Returns an array of all the TextRuns in the sheet.
- */
- public abstract List<List<HSLFTextParagraph>> getTextParagraphs();
-
- /**
- * Returns the (internal, RefID based) sheet number, as used
- * to in PersistPtr stuff.
- */
- public int _getSheetRefId() {
- return _container.getSheetId();
- }
-
- /**
- * Returns the (internal, SlideIdentifier based) sheet number, as used
- * to reference this sheet from other records.
- */
- public int _getSheetNumber() {
- return _sheetNo;
- }
-
- /**
- * Fetch the PPDrawing from the underlying record
- */
- public PPDrawing getPPDrawing() {
- return _container.getPPDrawing();
- }
-
- /**
- * Fetch the SlideShow we're attached to
- */
- public HSLFSlideShow getSlideShow() {
- return _slideShow;
- }
-
- /**
- * Return record container for this sheet
- */
- public SheetContainer getSheetContainer() {
- return _container;
- }
-
- /**
- * Set the SlideShow we're attached to.
- * Also passes it on to our child text paragraphs
- */
- @Internal
- protected void setSlideShow(HSLFSlideShow ss) {
- if (_slideShow != null) {
- throw new HSLFException("Can't change existing slideshow reference");
- }
-
- _slideShow = ss;
- List<List<HSLFTextParagraph>> trs = getTextParagraphs();
- if (trs == null) return;
- for (List<HSLFTextParagraph> ltp : trs) {
- HSLFTextParagraph.supplySheet(ltp, this);
- }
- }
-
-
- /**
- * Returns all shapes contained in this Sheet
- *
- * @return all shapes contained in this Sheet (Slide or Notes)
- */
- @Override
- public List<HSLFShape> getShapes() {
- PPDrawing ppdrawing = getPPDrawing();
-
- EscherContainerRecord dg = ppdrawing.getDgContainer();
- EscherContainerRecord spgr = null;
-
- for (Iterator<EscherRecord> it = dg.getChildIterator(); it.hasNext();) {
- EscherRecord rec = it.next();
- if (rec.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) {
- spgr = (EscherContainerRecord) rec;
- break;
- }
- }
- if (spgr == null) {
- throw new IllegalStateException("spgr not found");
- }
-
- List<HSLFShape> shapeList = new ArrayList<HSLFShape>();
- Iterator<EscherRecord> it = spgr.getChildIterator();
- if (it.hasNext()) {
- // skip first item
- it.next();
- }
- for (; it.hasNext();) {
- EscherContainerRecord sp = (EscherContainerRecord) it.next();
- HSLFShape sh = HSLFShapeFactory.createShape(sp, null);
- sh.setSheet(this);
- shapeList.add(sh);
- }
-
- return shapeList;
- }
-
- /**
- * Add a new Shape to this Slide
- *
- * @param shape - the Shape to add
- */
- public void addShape(HSLFShape shape) {
- PPDrawing ppdrawing = getPPDrawing();
-
- EscherContainerRecord dgContainer = ppdrawing.getDgContainer();
- EscherContainerRecord spgr = (EscherContainerRecord) HSLFShape.getEscherChild(dgContainer, EscherContainerRecord.SPGR_CONTAINER);
- spgr.addChildRecord(shape.getSpContainer());
-
- shape.setSheet(this);
- shape.setShapeId(allocateShapeId());
- shape.afterInsert(this);
- }
-
- /**
- * Allocates new shape id for the new drawing group id.
- *
- * @return a new shape id.
- */
- public int allocateShapeId()
- {
- EscherDggRecord dgg = _slideShow.getDocumentRecord().getPPDrawingGroup().getEscherDggRecord();
- EscherDgRecord dg = _container.getPPDrawing().getEscherDgRecord();
-
- dgg.setNumShapesSaved( dgg.getNumShapesSaved() + 1 );
-
- // Add to existing cluster if space available
- for (int i = 0; i < dgg.getFileIdClusters().length; i++)
- {
- EscherDggRecord.FileIdCluster c = dgg.getFileIdClusters()[i];
- if (c.getDrawingGroupId() == dg.getDrawingGroupId() && c.getNumShapeIdsUsed() != 1024)
- {
- int result = c.getNumShapeIdsUsed() + (1024 * (i+1));
- c.incrementShapeId();
- dg.setNumShapes( dg.getNumShapes() + 1 );
- dg.setLastMSOSPID( result );
- if (result >= dgg.getShapeIdMax())
- dgg.setShapeIdMax( result + 1 );
- return result;
- }
- }
-
- // Create new cluster
- dgg.addCluster( dg.getDrawingGroupId(), 0, false );
- dgg.getFileIdClusters()[dgg.getFileIdClusters().length-1].incrementShapeId();
- dg.setNumShapes( dg.getNumShapes() + 1 );
- int result = (1024 * dgg.getFileIdClusters().length);
- dg.setLastMSOSPID( result );
- if (result >= dgg.getShapeIdMax())
- dgg.setShapeIdMax( result + 1 );
- return result;
- }
-
- /**
- * Removes the specified shape from this sheet.
- *
- * @param shape shape to be removed from this sheet, if present.
- * @return <tt>true</tt> if the shape was deleted.
- */
- public boolean removeShape(HSLFShape shape) {
- PPDrawing ppdrawing = getPPDrawing();
-
- EscherContainerRecord dg = ppdrawing.getDgContainer();
- EscherContainerRecord spgr = dg.getChildById(EscherContainerRecord.SPGR_CONTAINER);
- if(spgr == null) {
- return false;
- }
-
- List<EscherRecord> lst = spgr.getChildRecords();
- boolean result = lst.remove(shape.getSpContainer());
- spgr.setChildRecords(lst);
- return result;
- }
-
- /**
- * Called by SlideShow ater a new sheet is created
- */
- public void onCreate(){
-
- }
-
- /**
- * Return the master sheet .
- */
- public abstract HSLFMasterSheet getMasterSheet();
-
- /**
- * Color scheme for this sheet.
- */
- public ColorSchemeAtom getColorScheme() {
- return _container.getColorScheme();
- }
-
- /**
- * Returns the background shape for this sheet.
- *
- * @return the background shape for this sheet.
- */
- public HSLFBackground getBackground() {
- if (_background == null) {
- PPDrawing ppdrawing = getPPDrawing();
-
- EscherContainerRecord dg = ppdrawing.getDgContainer();
- EscherContainerRecord spContainer = dg.getChildById(EscherContainerRecord.SP_CONTAINER);
- _background = new HSLFBackground(spContainer, null);
- _background.setSheet(this);
- }
- return _background;
- }
-
- @Override
- public void draw(Graphics2D graphics) {
- DrawFactory drawFact = DrawFactory.getInstance(graphics);
- Drawable draw = drawFact.getDrawable(this);
- draw.draw(graphics);
- }
-
- /**
- * Subclasses should call this method and update the array of text runs
- * when a text shape is added
- *
- * @param shape
- */
- protected void onAddTextShape(HSLFTextShape shape) {
- }
-
- /**
- * Return placeholder by text type
- *
- * @param type type of text, See {@link org.apache.poi.hslf.record.TextHeaderAtom}
- * @return <code>TextShape</code> or <code>null</code>
- */
- public HSLFTextShape getPlaceholderByTextType(int type){
- for (HSLFShape shape : getShapes()) {
- if(shape instanceof HSLFTextShape){
- HSLFTextShape tx = (HSLFTextShape)shape;
- if (tx.getRunType() == type) {
- return tx;
- }
- }
- }
- return null;
- }
-
- /**
- * Search text placeholer by its type
- *
- * @param type type of placeholder to search. See {@link org.apache.poi.hslf.record.OEPlaceholderAtom}
- * @return <code>TextShape</code> or <code>null</code>
- */
- public HSLFTextShape getPlaceholder(int type){
- for (HSLFShape shape : getShapes()) {
- if(shape instanceof HSLFTextShape){
- HSLFTextShape tx = (HSLFTextShape)shape;
- int placeholderId = 0;
- OEPlaceholderAtom oep = tx.getPlaceholderAtom();
- if(oep != null) {
- placeholderId = oep.getPlaceholderId();
- } else {
- //special case for files saved in Office 2007
- RoundTripHFPlaceholder12 hldr = tx.getClientDataRecord(RecordTypes.RoundTripHFPlaceholder12.typeID);
- if(hldr != null) placeholderId = hldr.getPlaceholderId();
- }
- if(placeholderId == type){
- return tx;
- }
- }
- }
- return null;
- }
-
- /**
- * Return programmable tag associated with this sheet, e.g. <code>___PPT12</code>.
- *
- * @return programmable tag associated with this sheet.
- */
- public String getProgrammableTag(){
- String tag = null;
- RecordContainer progTags = (RecordContainer)
- getSheetContainer().findFirstOfType(
- RecordTypes.ProgTags.typeID
- );
- if(progTags != null) {
- RecordContainer progBinaryTag = (RecordContainer)
- progTags.findFirstOfType(
- RecordTypes.ProgBinaryTag.typeID
- );
- if(progBinaryTag != null) {
- CString binaryTag = (CString)
- progBinaryTag.findFirstOfType(
- RecordTypes.CString.typeID
- );
- if(binaryTag != null) tag = binaryTag.getText();
- }
- }
-
- return tag;
-
- }
-
- public Iterator<HSLFShape> iterator() {
- return getShapes().iterator();
- }
-
-
- /**
- * @return whether shapes on the master sheet should be shown. By default master graphics is turned off.
- * Sheets that support the notion of master (slide, slideLayout) should override it and
- * check this setting
- */
- public boolean getFollowMasterGraphics() {
- return false;
- }
-
-
- @Override
- public HSLFTextBox createTextBox() {
- HSLFTextBox s = new HSLFTextBox();
- s.setHorizontalCentered(true);
- s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100));
- addShape(s);
- return s;
- }
-
- @Override
- public HSLFAutoShape createAutoShape() {
- HSLFAutoShape s = new HSLFAutoShape(ShapeType.RECT);
- s.setHorizontalCentered(true);
- s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100));
- addShape(s);
- return s;
- }
-
- @Override
- public HSLFFreeformShape createFreeform() {
- HSLFFreeformShape s = new HSLFFreeformShape();
- s.setHorizontalCentered(true);
- s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100));
- addShape(s);
- return s;
- }
-
- @Override
- public HSLFConnectorShape createConnector() {
- HSLFConnectorShape s = new HSLFConnectorShape();
- s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100));
- addShape(s);
- return s;
- }
-
- @Override
- public HSLFGroupShape createGroup() {
- HSLFGroupShape s = new HSLFGroupShape();
- s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100));
- addShape(s);
- return s;
- }
-
- @Override
- public HSLFPictureShape createPicture(PictureData pictureData) {
- if (!(pictureData instanceof HSLFPictureData)) {
- throw new IllegalArgumentException("pictureData needs to be of type HSLFPictureData");
- }
- HSLFPictureShape s = new HSLFPictureShape((HSLFPictureData)pictureData);
- s.setAnchor(new Rectangle2D.Double(0, 0, 100, 100));
- addShape(s);
- return s;
- }
-
- @Override
- public HSLFTable createTable(int numRows, int numCols) {
- if (numRows < 1 || numCols < 1) {
- throw new IllegalArgumentException("numRows and numCols must be greater than 0");
- }
- HSLFTable s = new HSLFTable(numRows,numCols);
- // anchor is set in constructor based on numRows/numCols
- addShape(s);
- return s;
- }
- }
|