예제 #1
0
  /**
   * Re-orders a slide, to a new position.
   *
   * @param oldSlideNumber The old slide number (1 based)
   * @param newSlideNumber The new slide number (1 based)
   */
  public void reorderSlide(int oldSlideNumber, int newSlideNumber) {
    // Ensure these numbers are valid
    if (oldSlideNumber < 1 || newSlideNumber < 1) {
      throw new IllegalArgumentException("Old and new slide numbers must be greater than 0");
    }
    if (oldSlideNumber > _slides.size() || newSlideNumber > _slides.size()) {
      throw new IllegalArgumentException(
          "Old and new slide numbers must not exceed the number of slides ("
              + _slides.size()
              + ")");
    }

    // The order of slides is defined by the order of slide atom sets in the
    // SlideListWithText container.
    SlideListWithText slwt = _documentRecord.getSlideSlideListWithText();
    SlideAtomsSet[] sas = slwt.getSlideAtomsSets();

    SlideAtomsSet tmp = sas[oldSlideNumber - 1];
    sas[oldSlideNumber - 1] = sas[newSlideNumber - 1];
    sas[newSlideNumber - 1] = tmp;

    Collections.swap(_slides, oldSlideNumber - 1, newSlideNumber - 1);
    _slides.get(newSlideNumber - 1).setSlideNumber(newSlideNumber);
    _slides.get(oldSlideNumber - 1).setSlideNumber(oldSlideNumber);

    ArrayList<Record> lst = new ArrayList<Record>();
    for (SlideAtomsSet s : sas) {
      lst.add(s.getSlidePersistAtom());
      lst.addAll(Arrays.asList(s.getSlideRecords()));
    }

    Record[] r = lst.toArray(new Record[lst.size()]);
    slwt.setChildRecord(r);
  }
예제 #2
0
  public static void main(String[] args) throws Exception {
    if (args.length < 1) {
      System.err.println("Need to give a filename");
      System.exit(1);
    }

    HSLFSlideShow ss = new HSLFSlideShow(args[0]);

    // Find the documents, and then their SLWT
    Record[] records = ss.getRecords();
    for (int i = 0; i < records.length; i++) {
      if (records[i] instanceof Document) {
        Record docRecord = records[i];
        Record[] docChildren = docRecord.getChildRecords();
        for (int j = 0; j < docChildren.length; j++) {
          if (docChildren[j] instanceof SlideListWithText) {
            System.out.println("Found SLWT at pos " + j + " in the Document at " + i);
            System.out.println("  Has " + docChildren[j].getChildRecords().length + " children");

            // Grab the SlideAtomSet's, which contain
            //  a SlidePersistAtom and then a bunch of text
            //  + related records
            SlideListWithText slwt = (SlideListWithText) docChildren[j];
            SlideListWithText.SlideAtomsSet[] thisSets = slwt.getSlideAtomsSets();
            System.out.println("  Has " + thisSets.length + " AtomSets in it");

            // Loop over the sets, showing what they contain
            for (int k = 0; k < thisSets.length; k++) {
              SlidePersistAtom spa = thisSets[k].getSlidePersistAtom();
              System.out.println("    " + k + " has slide id " + spa.getSlideIdentifier());
              System.out.println("    " + k + " has ref id " + spa.getRefID());

              // Loop over the records, printing the text
              Record[] slwtc = thisSets[k].getSlideRecords();
              for (int l = 0; l < slwtc.length; l++) {
                String text = null;
                if (slwtc[l] instanceof TextBytesAtom) {
                  TextBytesAtom tba = (TextBytesAtom) slwtc[l];
                  text = tba.getText();
                }
                if (slwtc[l] instanceof TextCharsAtom) {
                  TextCharsAtom tca = (TextCharsAtom) slwtc[l];
                  text = tca.getText();
                }

                if (text != null) {
                  text = text.replace('\r', '\n');
                  System.out.println("        ''" + text + "''");
                }
              }
            }
          }
        }
      }
    }
  }
예제 #3
0
  /**
   * Removes the slide at the given index (0-based).
   *
   * <p>Shifts any subsequent slides to the left (subtracts one from their slide numbers).
   *
   * @param index the index of the slide to remove (0-based)
   * @return the slide that was removed from the slide show.
   */
  public HSLFSlide removeSlide(int index) {
    int lastSlideIdx = _slides.size() - 1;
    if (index < 0 || index > lastSlideIdx) {
      throw new IllegalArgumentException(
          "Slide index (" + index + ") is out of range (0.." + lastSlideIdx + ")");
    }

    SlideListWithText slwt = _documentRecord.getSlideSlideListWithText();
    SlideAtomsSet[] sas = slwt.getSlideAtomsSets();

    List<Record> records = new ArrayList<Record>();
    List<SlideAtomsSet> sa = new ArrayList<SlideAtomsSet>(Arrays.asList(sas));

    HSLFSlide removedSlide = _slides.remove(index);
    _notes.remove(removedSlide.getNotes());
    sa.remove(index);

    int i = 0;
    for (HSLFSlide s : _slides) s.setSlideNumber(i++);

    for (SlideAtomsSet s : sa) {
      records.add(s.getSlidePersistAtom());
      records.addAll(Arrays.asList(s.getSlideRecords()));
    }
    if (sa.isEmpty()) {
      _documentRecord.removeSlideListWithText(slwt);
    } else {
      slwt.setSlideAtomsSets(sa.toArray(new SlideAtomsSet[sa.size()]));
      slwt.setChildRecord(records.toArray(new Record[records.size()]));
    }

    // if the removed slide had notes - remove references to them too

    int notesId =
        (removedSlide != null) ? removedSlide.getSlideRecord().getSlideAtom().getNotesID() : 0;
    if (notesId != 0) {
      SlideListWithText nslwt = _documentRecord.getNotesSlideListWithText();
      records = new ArrayList<Record>();
      ArrayList<SlideAtomsSet> na = new ArrayList<SlideAtomsSet>();
      for (SlideAtomsSet ns : nslwt.getSlideAtomsSets()) {
        if (ns.getSlidePersistAtom().getSlideIdentifier() == notesId) continue;
        na.add(ns);
        records.add(ns.getSlidePersistAtom());
        if (ns.getSlideRecords() != null) {
          records.addAll(Arrays.asList(ns.getSlideRecords()));
        }
      }
      if (na.isEmpty()) {
        _documentRecord.removeSlideListWithText(nslwt);
      } else {
        nslwt.setSlideAtomsSets(na.toArray(new SlideAtomsSet[na.size()]));
        nslwt.setChildRecord(records.toArray(new Record[records.size()]));
      }
    }

    return removedSlide;
  }
예제 #4
0
  /**
   * Opens a new copy of SlideShow C, writes the active SlideListWithText out, and compares it to
   * the write out of the supplied SlideShow. Also compares the contents.
   *
   * @param s
   */
  private void assertMatchesSLTWC(SlideShow s) throws Exception {
    // Grab a new copy of slideshow C
    SlideShow refC = new SlideShow(_slTests.openResourceAsStream(filenameC));

    // Write out the 2nd SLWT in the active document
    SlideListWithText refSLWT = refC.getDocumentRecord().getSlideListWithTexts()[1];
    byte[] raw_slwt = writeRecord(refSLWT);

    // Write out the same for the supplied slideshow
    SlideListWithText s_SLWT = s.getDocumentRecord().getSlideListWithTexts()[1];
    byte[] s_slwt = writeRecord(s_SLWT);

    // Check the records are the same
    assertEquals(refSLWT.getChildRecords().length, s_SLWT.getChildRecords().length);
    for (int i = 0; i < refSLWT.getChildRecords().length; i++) {
      Record ref_r = refSLWT.getChildRecords()[i];
      Record s_r = s_SLWT.getChildRecords()[i];

      byte[] r_rb = writeRecord(ref_r);
      byte[] s_rb = writeRecord(s_r);
      assertEquals(r_rb.length, s_rb.length);
      for (int j = 0; j < r_rb.length; j++) {
        assertEquals(r_rb[j], s_rb[j]);
      }
    }

    // Check the bytes are the same
    assertEquals(raw_slwt.length, s_slwt.length);
    for (int i = 0; i < raw_slwt.length; i++) {
      assertEquals(raw_slwt[i], s_slwt[i]);
    }
  }
예제 #5
0
  /**
   * Create a blank <code>Slide</code>.
   *
   * @return the created <code>Slide</code>
   */
  @Override
  public HSLFSlide createSlide() {
    SlideListWithText slist = null;

    // We need to add the records to the SLWT that deals
    // with Slides.
    // Add it, if it doesn't exist
    slist = _documentRecord.getSlideSlideListWithText();
    if (slist == null) {
      // Need to add a new one
      slist = new SlideListWithText();
      slist.setInstance(SlideListWithText.SLIDES);
      _documentRecord.addSlideListWithText(slist);
    }

    // Grab the SlidePersistAtom with the highest Slide Number.
    // (Will stay as null if no SlidePersistAtom exists yet in
    // the slide, or only master slide's ones do)
    SlidePersistAtom prev = null;
    for (SlideAtomsSet sas : slist.getSlideAtomsSets()) {
      SlidePersistAtom spa = sas.getSlidePersistAtom();
      if (spa.getSlideIdentifier() < 0) {
        // This is for a master slide
        // Odd, since we only deal with the Slide SLWT
      } else {
        // Must be for a real slide
        if (prev == null) {
          prev = spa;
        }
        if (prev.getSlideIdentifier() < spa.getSlideIdentifier()) {
          prev = spa;
        }
      }
    }

    // Set up a new SlidePersistAtom for this slide
    SlidePersistAtom sp = new SlidePersistAtom();

    // First slideId is always 256
    sp.setSlideIdentifier(prev == null ? 256 : (prev.getSlideIdentifier() + 1));

    // Add this new SlidePersistAtom to the SlideListWithText
    slist.addSlidePersistAtom(sp);

    // Create a new Slide
    HSLFSlide slide = new HSLFSlide(sp.getSlideIdentifier(), sp.getRefID(), _slides.size() + 1);
    slide.setSlideShow(this);
    slide.onCreate();

    // Add in to the list of Slides
    _slides.add(slide);
    logger.log(
        POILogger.INFO,
        "Added slide "
            + _slides.size()
            + " with ref "
            + sp.getRefID()
            + " and identifier "
            + sp.getSlideIdentifier());

    // Add the core records for this new Slide to the record tree
    org.apache.poi.hslf.record.Slide slideRecord = slide.getSlideRecord();
    int psrId = addPersistentObject(slideRecord);
    sp.setRefID(psrId);
    slideRecord.setSheetId(psrId);

    slide.setMasterSheet(_masters.get(0));
    // All done and added
    return slide;
  }
예제 #6
0
  /** Build up model level Slide and Notes objects, from the underlying records. */
  private void buildSlidesAndNotes() {
    // Ensure we really found a Document record earlier
    // If we didn't, then the file is probably corrupt
    if (_documentRecord == null) {
      throw new CorruptPowerPointFileException(
          "The PowerPoint file didn't contain a Document Record in its PersistPtr blocks. It is probably corrupt.");
    }

    // Fetch the SlideListWithTexts in the most up-to-date Document Record
    //
    // As far as we understand it:
    // * The first SlideListWithText will contain a SlideAtomsSet
    // for each of the master slides
    // * The second SlideListWithText will contain a SlideAtomsSet
    // for each of the slides, in their current order
    // These SlideAtomsSets will normally contain text
    // * The third SlideListWithText (if present), will contain a
    // SlideAtomsSet for each Notes
    // These SlideAtomsSets will not normally contain text
    //
    // Having indentified the masters, slides and notes + their orders,
    // we have to go and find their matching records
    // We always use the latest versions of these records, and use the
    // SlideAtom/NotesAtom to match them with the StyleAtomSet

    SlideListWithText masterSLWT = _documentRecord.getMasterSlideListWithText();
    SlideListWithText slidesSLWT = _documentRecord.getSlideSlideListWithText();
    SlideListWithText notesSLWT = _documentRecord.getNotesSlideListWithText();

    // Find master slides
    // These can be MainMaster records, but oddly they can also be
    // Slides or Notes, and possibly even other odd stuff....
    // About the only thing you can say is that the master details are in
    // the first SLWT.
    if (masterSLWT != null) {
      for (SlideAtomsSet sas : masterSLWT.getSlideAtomsSets()) {
        Record r = getCoreRecordForSAS(sas);
        int sheetNo = sas.getSlidePersistAtom().getSlideIdentifier();
        if (r instanceof org.apache.poi.hslf.record.Slide) {
          HSLFTitleMaster master =
              new HSLFTitleMaster((org.apache.poi.hslf.record.Slide) r, sheetNo);
          master.setSlideShow(this);
          _titleMasters.add(master);
        } else if (r instanceof org.apache.poi.hslf.record.MainMaster) {
          HSLFSlideMaster master =
              new HSLFSlideMaster((org.apache.poi.hslf.record.MainMaster) r, sheetNo);
          master.setSlideShow(this);
          _masters.add(master);
        }
      }
    }

    // Having sorted out the masters, that leaves the notes and slides

    // Start by finding the notes records to go with the entries in
    // notesSLWT
    org.apache.poi.hslf.record.Notes[] notesRecords;
    Map<Integer, Integer> slideIdToNotes = new HashMap<Integer, Integer>();
    if (notesSLWT == null) {
      // None
      notesRecords = new org.apache.poi.hslf.record.Notes[0];
    } else {
      // Match up the records and the SlideAtomSets
      List<org.apache.poi.hslf.record.Notes> notesRecordsL =
          new ArrayList<org.apache.poi.hslf.record.Notes>();
      int idx = -1;
      for (SlideAtomsSet notesSet : notesSLWT.getSlideAtomsSets()) {
        idx++;
        // Get the right core record
        Record r = getCoreRecordForSAS(notesSet);
        SlidePersistAtom spa = notesSet.getSlidePersistAtom();

        String loggerLoc =
            "A Notes SlideAtomSet at " + idx + " said its record was at refID " + spa.getRefID();

        // Ensure it really is a notes record
        if (r == null || r instanceof org.apache.poi.hslf.record.Notes) {
          if (r == null) {
            logger.log(
                POILogger.WARN, loggerLoc + ", but that record didn't exist - record ignored.");
          }
          // we need to add also null-records, otherwise the index references to other existing
          // don't work anymore
          org.apache.poi.hslf.record.Notes notesRecord = (org.apache.poi.hslf.record.Notes) r;
          notesRecordsL.add(notesRecord);

          // Record the match between slide id and these notes
          int slideId = spa.getSlideIdentifier();
          slideIdToNotes.put(slideId, idx);
        } else {
          logger.log(POILogger.ERROR, loggerLoc + ", but that was actually a " + r);
        }
      }
      notesRecords = new org.apache.poi.hslf.record.Notes[notesRecordsL.size()];
      notesRecords = notesRecordsL.toArray(notesRecords);
    }

    // Now, do the same thing for our slides
    org.apache.poi.hslf.record.Slide[] slidesRecords;
    SlideAtomsSet[] slidesSets = new SlideAtomsSet[0];
    if (slidesSLWT == null) {
      // None
      slidesRecords = new org.apache.poi.hslf.record.Slide[0];
    } else {
      // Match up the records and the SlideAtomSets
      slidesSets = slidesSLWT.getSlideAtomsSets();
      slidesRecords = new org.apache.poi.hslf.record.Slide[slidesSets.length];
      for (int i = 0; i < slidesSets.length; i++) {
        // Get the right core record
        Record r = getCoreRecordForSAS(slidesSets[i]);

        // Ensure it really is a slide record
        if (r instanceof org.apache.poi.hslf.record.Slide) {
          slidesRecords[i] = (org.apache.poi.hslf.record.Slide) r;
        } else {
          logger.log(
              POILogger.ERROR,
              "A Slide SlideAtomSet at "
                  + i
                  + " said its record was at refID "
                  + slidesSets[i].getSlidePersistAtom().getRefID()
                  + ", but that was actually a "
                  + r);
        }
      }
    }

    // Finally, generate model objects for everything
    // Notes first
    for (org.apache.poi.hslf.record.Notes n : notesRecords) {
      HSLFNotes hn = null;
      if (n != null) {
        hn = new HSLFNotes(n);
        hn.setSlideShow(this);
      }
      _notes.add(hn);
    }
    // Then slides
    for (int i = 0; i < slidesRecords.length; i++) {
      SlideAtomsSet sas = slidesSets[i];
      int slideIdentifier = sas.getSlidePersistAtom().getSlideIdentifier();

      // Do we have a notes for this?
      HSLFNotes notes = null;
      // Slide.SlideAtom.notesId references the corresponding notes slide.
      // 0 if slide has no notes.
      int noteId = slidesRecords[i].getSlideAtom().getNotesID();
      if (noteId != 0) {
        Integer notesPos = slideIdToNotes.get(noteId);
        if (notesPos != null) {
          notes = _notes.get(notesPos);
        } else {
          logger.log(POILogger.ERROR, "Notes not found for noteId=" + noteId);
        }
      }

      // Now, build our slide
      HSLFSlide hs = new HSLFSlide(slidesRecords[i], notes, sas, slideIdentifier, (i + 1));
      hs.setSlideShow(this);
      _slides.add(hs);
    }
  }