Save This Page
Home » poi-src-3.2-FINAL-20081019 » org.apache » poi » hslf » model » [javadoc | source]
    1   /* ====================================================================
    2      Licensed to the Apache Software Foundation (ASF) under one or more
    3      contributor license agreements.  See the NOTICE file distributed with
    4      this work for additional information regarding copyright ownership.
    5      The ASF licenses this file to You under the Apache License, Version 2.0
    6      (the "License"); you may not use this file except in compliance with
    7      the License.  You may obtain a copy of the License at
    8   
    9          http://www.apache.org/licenses/LICENSE-2.0
   10   
   11      Unless required by applicable law or agreed to in writing, software
   12      distributed under the License is distributed on an "AS IS" BASIS,
   13      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14      See the License for the specific language governing permissions and
   15      limitations under the License.
   16   ==================================================================== */
   17   
   18   
   19   package org.apache.poi.hslf.model;
   20   
   21   import org.apache.poi.ddf;
   22   import org.apache.poi.hslf.record;
   23   import org.apache.poi.hslf.usermodel.SlideShow;
   24   import org.apache.poi.util.POILogger;
   25   
   26   import java.util.ArrayList;
   27   import java.util.Iterator;
   28   import java.util.List;
   29   import java.util.Vector;
   30   import java.awt;
   31   
   32   /**
   33    * This class defines the common format of "Sheets" in a powerpoint
   34    * document. Such sheets could be Slides, Notes, Master etc
   35    *
   36    * @author Nick Burch
   37    * @author Yegor Kozlov
   38    */
   39   
   40   public abstract class Sheet {
   41       /**
   42        * The <code>SlideShow</code> we belong to
   43        */
   44       private SlideShow _slideShow;
   45   
   46       /**
   47        * Sheet background
   48        */
   49       private Background _background;
   50   
   51       /**
   52        * Record container that holds sheet data.
   53        * For slides it is org.apache.poi.hslf.record.Slide,
   54        * for notes it is org.apache.poi.hslf.record.Notes,
   55        * for slide masters it is org.apache.poi.hslf.record.SlideMaster, etc.
   56        */
   57       private SheetContainer _container;
   58   
   59       private int _sheetNo;
   60   
   61       public Sheet(SheetContainer container, int sheetNo) {
   62           _container = container;
   63           _sheetNo = sheetNo;
   64       }
   65   
   66       /**
   67        * Returns an array of all the TextRuns in the sheet.
   68        */
   69       public abstract TextRun[] getTextRuns();
   70   
   71       /**
   72        * Returns the (internal, RefID based) sheet number, as used
   73        * to in PersistPtr stuff.
   74        */
   75       public int _getSheetRefId() {
   76           return _container.getSheetId();
   77       }
   78   
   79       /**
   80        * Returns the (internal, SlideIdentifier based) sheet number, as used
   81        * to reference this sheet from other records.
   82        */
   83       public int _getSheetNumber() {
   84           return _sheetNo;
   85       }
   86   
   87       /**
   88        * Fetch the PPDrawing from the underlying record
   89        */
   90       protected PPDrawing getPPDrawing() {
   91           return _container.getPPDrawing();
   92       }
   93   
   94       /**
   95        * Fetch the SlideShow we're attached to
   96        */
   97       public SlideShow getSlideShow() {
   98           return _slideShow;
   99       }
  100   
  101       /**
  102        * Return record container for this sheet
  103        */
  104       public SheetContainer getSheetContainer() {
  105           return _container;
  106       }
  107   
  108       /**
  109        * Set the SlideShow we're attached to.
  110        * Also passes it on to our child RichTextRuns
  111        */
  112       public void setSlideShow(SlideShow ss) {
  113           _slideShow = ss;
  114           TextRun[] trs = getTextRuns();
  115           if (trs != null) {
  116               for (int i = 0; i < trs.length; i++) {
  117                   trs[i].supplySlideShow(_slideShow);
  118               }
  119           }
  120       }
  121   
  122   
  123       /**
  124        * For a given PPDrawing, grab all the TextRuns
  125        */
  126       public static TextRun[] findTextRuns(PPDrawing ppdrawing) {
  127           Vector runsV = new Vector();
  128           EscherTextboxWrapper[] wrappers = ppdrawing.getTextboxWrappers();
  129           for (int i = 0; i < wrappers.length; i++) {
  130               int s1 = runsV.size();
  131               findTextRuns(wrappers[i].getChildRecords(), runsV);
  132               int s2 = runsV.size();
  133               if (s2 != s1){
  134                   TextRun t = (TextRun) runsV.get(runsV.size()-1);
  135                   t.setShapeId(wrappers[i].getShapeId());
  136               }
  137           }
  138           TextRun[] runs = new TextRun[runsV.size()];
  139           for (int i = 0; i < runs.length; i++) {
  140               runs[i] = (TextRun) runsV.get(i);
  141           }
  142           return runs;
  143       }
  144   
  145       /**
  146        * Scans through the supplied record array, looking for
  147        * a TextHeaderAtom followed by one of a TextBytesAtom or
  148        * a TextCharsAtom. Builds up TextRuns from these
  149        *
  150        * @param records the records to build from
  151        * @param found   vector to add any found to
  152        */
  153       protected static void findTextRuns(Record[] records, Vector found) {
  154           // Look for a TextHeaderAtom
  155           for (int i = 0, slwtIndex=0; i < (records.length - 1); i++) {
  156               if (records[i] instanceof TextHeaderAtom) {
  157                   TextRun trun = null;
  158                   TextHeaderAtom tha = (TextHeaderAtom) records[i];
  159                   StyleTextPropAtom stpa = null;
  160   
  161                   // Look for a subsequent StyleTextPropAtom
  162                   if (i < (records.length - 2)) {
  163                       if (records[i + 2] instanceof StyleTextPropAtom) {
  164                           stpa = (StyleTextPropAtom) records[i + 2];
  165                       }
  166                   }
  167   
  168                   // See what follows the TextHeaderAtom
  169                   if (records[i + 1] instanceof TextCharsAtom) {
  170                       TextCharsAtom tca = (TextCharsAtom) records[i + 1];
  171                       trun = new TextRun(tha, tca, stpa);
  172                   } else if (records[i + 1] instanceof TextBytesAtom) {
  173                       TextBytesAtom tba = (TextBytesAtom) records[i + 1];
  174                       trun = new TextRun(tha, tba, stpa);
  175                   } else if (records[i + 1].getRecordType() == 4001l) {
  176                       // StyleTextPropAtom - Safe to ignore
  177                   } else if (records[i + 1].getRecordType() == 4010l) {
  178                       // TextSpecInfoAtom - Safe to ignore
  179                   } else {
  180                       System.err.println("Found a TextHeaderAtom not followed by a TextBytesAtom or TextCharsAtom: Followed by " + records[i + 1].getRecordType());
  181                   }
  182   
  183                   if (trun != null) {
  184                       ArrayList lst = new ArrayList();
  185                       for (int j = i; j < records.length; j++) {
  186                           if(j > i && records[j] instanceof TextHeaderAtom) break;
  187                           lst.add(records[j]);
  188                       }
  189                       Record[] recs = new Record[lst.size()];
  190                       lst.toArray(recs);
  191                       trun._records = recs;
  192                       trun.setIndex(slwtIndex);
  193                       
  194                       found.add(trun);
  195                       i++;
  196                   } else {
  197                       // Not a valid one, so skip on to next and look again
  198                   }
  199                   slwtIndex++;
  200               }
  201           }
  202       }
  203   
  204       /**
  205        * Returns all shapes contained in this Sheet
  206        *
  207        * @return all shapes contained in this Sheet (Slide or Notes)
  208        */
  209       public Shape[] getShapes() {
  210           PPDrawing ppdrawing = getPPDrawing();
  211   
  212           EscherContainerRecord dg = (EscherContainerRecord) ppdrawing.getEscherRecords()[0];
  213           EscherContainerRecord spgr = null;
  214           List ch = dg.getChildRecords();
  215   
  216           for (Iterator it = ch.iterator(); it.hasNext();) {
  217               EscherRecord rec = (EscherRecord) it.next();
  218               if (rec.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) {
  219                   spgr = (EscherContainerRecord) rec;
  220                   break;
  221               }
  222           }
  223           ch = spgr.getChildRecords();
  224   
  225           ArrayList shapes = new ArrayList();
  226           for (int i = 1; i < ch.size(); i++) {
  227               EscherContainerRecord sp = (EscherContainerRecord) ch.get(i);
  228               Shape sh = ShapeFactory.createShape(sp, null);
  229               sh.setSheet(this);
  230               shapes.add(sh);
  231           }
  232   
  233           return (Shape[]) shapes.toArray(new Shape[shapes.size()]);
  234       }
  235   
  236       /**
  237        * Add a new Shape to this Slide
  238        *
  239        * @param shape - the Shape to add
  240        */
  241       public void addShape(Shape shape) {
  242           PPDrawing ppdrawing = getPPDrawing();
  243   
  244           EscherContainerRecord dgContainer = (EscherContainerRecord) ppdrawing.getEscherRecords()[0];
  245           EscherContainerRecord spgr = (EscherContainerRecord) Shape.getEscherChild(dgContainer, EscherContainerRecord.SPGR_CONTAINER);
  246           spgr.addChildRecord(shape.getSpContainer());
  247   
  248           shape.setSheet(this);
  249           shape.setShapeId(allocateShapeId());
  250           shape.afterInsert(this);
  251       }
  252   
  253       /**
  254        * Allocates new shape id for the new drawing group id.
  255        *
  256        * @return a new shape id.
  257        */
  258       public int allocateShapeId()
  259       {
  260           EscherDggRecord dgg = _slideShow.getDocumentRecord().getPPDrawingGroup().getEscherDggRecord();
  261           EscherDgRecord dg = _container.getPPDrawing().getEscherDgRecord();
  262   
  263           dgg.setNumShapesSaved( dgg.getNumShapesSaved() + 1 );
  264   
  265           // Add to existing cluster if space available
  266           for (int i = 0; i < dgg.getFileIdClusters().length; i++)
  267           {
  268               EscherDggRecord.FileIdCluster c = dgg.getFileIdClusters()[i];
  269               if (c.getDrawingGroupId() == dg.getDrawingGroupId() && c.getNumShapeIdsUsed() != 1024)
  270               {
  271                   int result = c.getNumShapeIdsUsed() + (1024 * (i+1));
  272                   c.incrementShapeId();
  273                   dg.setNumShapes( dg.getNumShapes() + 1 );
  274                   dg.setLastMSOSPID( result );
  275                   if (result >= dgg.getShapeIdMax())
  276                       dgg.setShapeIdMax( result + 1 );
  277                   return result;
  278               }
  279           }
  280   
  281           // Create new cluster
  282           dgg.addCluster( dg.getDrawingGroupId(), 0, false );
  283           dgg.getFileIdClusters()[dgg.getFileIdClusters().length-1].incrementShapeId();
  284           dg.setNumShapes( dg.getNumShapes() + 1 );
  285           int result = (1024 * dgg.getFileIdClusters().length);
  286           dg.setLastMSOSPID( result );
  287           if (result >= dgg.getShapeIdMax())
  288               dgg.setShapeIdMax( result + 1 );
  289           return result;
  290       }
  291   
  292       /**
  293        * Removes the specified shape from this sheet.
  294        *
  295        * @param shape shape to be removed from this sheet, if present.
  296        * @return <tt>true</tt> if the shape was deleted.
  297        */
  298       public boolean removeShape(Shape shape) {
  299           PPDrawing ppdrawing = getPPDrawing();
  300   
  301           EscherContainerRecord dg = (EscherContainerRecord) ppdrawing.getEscherRecords()[0];
  302           EscherContainerRecord spgr = null;
  303   
  304           for (Iterator it = dg.getChildRecords().iterator(); it.hasNext();) {
  305               EscherRecord rec = (EscherRecord) it.next();
  306               if (rec.getRecordId() == EscherContainerRecord.SPGR_CONTAINER) {
  307                   spgr = (EscherContainerRecord) rec;
  308                   break;
  309               }
  310           }
  311           if(spgr == null) return false;
  312   
  313           List lst = spgr.getChildRecords();
  314           return lst.remove(shape.getSpContainer());
  315       }
  316   
  317       /**
  318        * Called by SlideShow ater a new sheet is created
  319        */
  320       public void onCreate(){
  321   
  322       }
  323   
  324       /**
  325        * Return the master sheet .
  326        */
  327       public abstract MasterSheet getMasterSheet();
  328   
  329       /**
  330        * Color scheme for this sheet.
  331        */
  332       public ColorSchemeAtom getColorScheme() {
  333           return _container.getColorScheme();
  334       }
  335   
  336       /**
  337        * Returns the background shape for this sheet.
  338        *
  339        * @return the background shape for this sheet.
  340        */
  341       public Background getBackground() {
  342           if (_background == null) {
  343               PPDrawing ppdrawing = getPPDrawing();
  344   
  345               EscherContainerRecord dg = (EscherContainerRecord) ppdrawing.getEscherRecords()[0];
  346               EscherContainerRecord spContainer = null;
  347               List ch = dg.getChildRecords();
  348   
  349               for (Iterator it = ch.iterator(); it.hasNext();) {
  350                   EscherRecord rec = (EscherRecord) it.next();
  351                   if (rec.getRecordId() == EscherContainerRecord.SP_CONTAINER) {
  352                       spContainer = (EscherContainerRecord) rec;
  353                       break;
  354                   }
  355               }
  356               _background = new Background(spContainer, null);
  357               _background.setSheet(this);
  358           }
  359           return _background;
  360       }
  361   
  362       public void draw(Graphics2D graphics){
  363   
  364       }
  365   }

Save This Page
Home » poi-src-3.2-FINAL-20081019 » org.apache » poi » hslf » model » [javadoc | source]