View | Details | Raw Unified | Return to bug 48593
Collapse All | Expand All

(-)src/scratchpad/src/org/apache/poi/hslf/usermodel/SlideShow.java (-85 / +115 lines)
Lines 723-775 Link Here
723
723
724
		// Add the core records for this new Slide to the record tree
724
		// Add the core records for this new Slide to the record tree
725
		org.apache.poi.hslf.record.Slide slideRecord = slide.getSlideRecord();
725
		org.apache.poi.hslf.record.Slide slideRecord = slide.getSlideRecord();
726
		int slideRecordPos = _hslfSlideShow.appendRootLevelRecord(slideRecord);
726
		int psrId = addPersistentObject(slideRecord);
727
		_records = _hslfSlideShow.getRecords();
728
729
		// Add the new Slide into the PersistPtr stuff
730
		int offset = 0;
731
		int slideOffset = 0;
732
		PersistPtrHolder ptr = null;
733
		UserEditAtom usr = null;
734
		for (int i = 0; i < _records.length; i++) {
735
			Record record = _records[i];
736
			ByteArrayOutputStream out = new ByteArrayOutputStream();
737
			try {
738
				record.writeOut(out);
739
			} catch (IOException e) {
740
				throw new HSLFException(e);
741
			}
742
743
			// Grab interesting records as they come past
744
			if (_records[i].getRecordType() == RecordTypes.PersistPtrIncrementalBlock.typeID) {
745
				ptr = (PersistPtrHolder) _records[i];
746
			}
747
			if (_records[i].getRecordType() == RecordTypes.UserEditAtom.typeID) {
748
				usr = (UserEditAtom) _records[i];
749
			}
750
751
			if (i == slideRecordPos) {
752
				slideOffset = offset;
753
			}
754
			offset += out.size();
755
		}
756
757
		// persist ID is UserEditAtom.maxPersistWritten + 1
758
		int psrId = usr.getMaxPersistWritten() + 1;
759
		sp.setRefID(psrId);
727
		sp.setRefID(psrId);
760
		slideRecord.setSheetId(psrId);
728
		slideRecord.setSheetId(psrId);
761
729
		
762
		// Last view is now of the slide
763
		usr.setLastViewType((short) UserEditAtom.LAST_VIEW_SLIDE_VIEW);
764
		usr.setMaxPersistWritten(psrId); // increment the number of persit
765
										 // objects
766
767
		// Add the new slide into the last PersistPtr
768
		// (Also need to tell it where it is)
769
		slideRecord.setLastOnDiskOffset(slideOffset);
770
		ptr.addSlideLookup(sp.getRefID(), slideOffset);
771
		logger.log(POILogger.INFO, "New slide ended up at " + slideOffset);
772
773
		slide.setMasterSheet(_masters[0]);
730
		slide.setMasterSheet(_masters[0]);
774
		// All done and added
731
		// All done and added
775
		return slide;
732
		return slide;
Lines 978-993 Link Here
978
	 * @return 0-based index of the movie
935
	 * @return 0-based index of the movie
979
	 */
936
	 */
980
	public int addMovie(String path, int type) {
937
	public int addMovie(String path, int type) {
981
		ExObjList lst = (ExObjList) _documentRecord.findFirstOfType(RecordTypes.ExObjList.typeID);
982
		if (lst == null) {
983
			lst = new ExObjList();
984
			_documentRecord.addChildAfter(lst, _documentRecord.getDocumentAtom());
985
		}
986
987
		ExObjListAtom objAtom = lst.getExObjListAtom();
988
		// increment the object ID seed
989
		int objectId = (int) objAtom.getObjectIDSeed() + 1;
990
		objAtom.setObjectIDSeed(objectId);
991
		ExMCIMovie mci;
938
		ExMCIMovie mci;
992
		switch (type) {
939
		switch (type) {
993
			case MovieShape.MOVIE_MPEG:
940
			case MovieShape.MOVIE_MPEG:
Lines 1000-1010 Link Here
1000
				throw new IllegalArgumentException("Unsupported Movie: " + type);
947
				throw new IllegalArgumentException("Unsupported Movie: " + type);
1001
		}
948
		}
1002
949
1003
		lst.appendChildRecord(mci);
1004
		ExVideoContainer exVideo = mci.getExVideo();
950
		ExVideoContainer exVideo = mci.getExVideo();
1005
		exVideo.getExMediaAtom().setObjectId(objectId);
1006
		exVideo.getExMediaAtom().setMask(0xE80000);
951
		exVideo.getExMediaAtom().setMask(0xE80000);
1007
		exVideo.getPathAtom().setText(path);
952
		exVideo.getPathAtom().setText(path);
953
954
		int objectId = addToObjListAtom(mci);
955
		exVideo.getExMediaAtom().setObjectId(objectId);
956
		
1008
		return objectId;
957
		return objectId;
1009
	}
958
	}
1010
959
Lines 1019-1045 Link Here
1019
	 * @return 0-based index of the control
968
	 * @return 0-based index of the control
1020
	 */
969
	 */
1021
	public int addControl(String name, String progId) {
970
	public int addControl(String name, String progId) {
1022
		ExObjList lst = (ExObjList) _documentRecord.findFirstOfType(RecordTypes.ExObjList.typeID);
1023
		if (lst == null) {
1024
			lst = new ExObjList();
1025
			_documentRecord.addChildAfter(lst, _documentRecord.getDocumentAtom());
1026
		}
1027
		ExObjListAtom objAtom = lst.getExObjListAtom();
1028
		// increment the object ID seed
1029
		int objectId = (int) objAtom.getObjectIDSeed() + 1;
1030
		objAtom.setObjectIDSeed(objectId);
1031
		ExControl ctrl = new ExControl();
971
		ExControl ctrl = new ExControl();
972
		ctrl.setProgId(progId);
973
		ctrl.setMenuName(name);
974
		ctrl.setClipboardName(name);
975
		
1032
		ExOleObjAtom oleObj = ctrl.getExOleObjAtom();
976
		ExOleObjAtom oleObj = ctrl.getExOleObjAtom();
1033
		oleObj.setObjID(objectId);
1034
		oleObj.setDrawAspect(ExOleObjAtom.DRAW_ASPECT_VISIBLE);
977
		oleObj.setDrawAspect(ExOleObjAtom.DRAW_ASPECT_VISIBLE);
1035
		oleObj.setType(ExOleObjAtom.TYPE_CONTROL);
978
		oleObj.setType(ExOleObjAtom.TYPE_CONTROL);
1036
		oleObj.setSubType(ExOleObjAtom.SUBTYPE_DEFAULT);
979
		oleObj.setSubType(ExOleObjAtom.SUBTYPE_DEFAULT);
1037
980
		
1038
		ctrl.setProgId(progId);
981
		int objectId = addToObjListAtom(ctrl);
1039
		ctrl.setMenuName(name);
982
		oleObj.setObjID(objectId);
1040
		ctrl.setClipboardName(name);
1041
		lst.addChildAfter(ctrl, objAtom);
1042
1043
		return objectId;
983
		return objectId;
1044
	}
984
	}
1045
985
Lines 1049-1067 Link Here
1049
	 * @return 0-based index of the hyperlink
989
	 * @return 0-based index of the hyperlink
1050
	 */
990
	 */
1051
	public int addHyperlink(Hyperlink link) {
991
	public int addHyperlink(Hyperlink link) {
1052
		ExObjList lst = (ExObjList) _documentRecord.findFirstOfType(RecordTypes.ExObjList.typeID);
1053
		if (lst == null) {
1054
			lst = new ExObjList();
1055
			_documentRecord.addChildAfter(lst, _documentRecord.getDocumentAtom());
1056
		}
1057
		ExObjListAtom objAtom = lst.getExObjListAtom();
1058
		// increment the object ID seed
1059
		int objectId = (int) objAtom.getObjectIDSeed() + 1;
1060
		objAtom.setObjectIDSeed(objectId);
1061
1062
		ExHyperlink ctrl = new ExHyperlink();
992
		ExHyperlink ctrl = new ExHyperlink();
1063
		ExHyperlinkAtom obj = ctrl.getExHyperlinkAtom();
993
		ExHyperlinkAtom obj = ctrl.getExHyperlinkAtom();
1064
		obj.setNumber(objectId);
1065
        if(link.getType() == Hyperlink.LINK_SLIDENUMBER) {
994
        if(link.getType() == Hyperlink.LINK_SLIDENUMBER) {
1066
            ctrl.setLinkURL(link.getAddress(), 0x30);
995
            ctrl.setLinkURL(link.getAddress(), 0x30);
1067
        } else {
996
        } else {
Lines 1068-1076 Link Here
1068
            ctrl.setLinkURL(link.getAddress());
997
            ctrl.setLinkURL(link.getAddress());
1069
        }
998
        }
1070
		ctrl.setLinkTitle(link.getTitle());
999
		ctrl.setLinkTitle(link.getTitle());
1071
		lst.addChildAfter(ctrl, objAtom);
1000
1001
		int objectId = addToObjListAtom(ctrl);
1072
		link.setId(objectId);
1002
		link.setId(objectId);
1003
		obj.setNumber(objectId);
1073
1004
1074
		return objectId;
1005
		return objectId;
1075
	}
1006
	}
1007
1008
	protected int addToObjListAtom(RecordContainer exObj) {
1009
		ExObjList lst = (ExObjList) _documentRecord.findFirstOfType(RecordTypes.ExObjList.typeID);
1010
		if (lst == null) {
1011
			lst = new ExObjList();
1012
			_documentRecord.addChildAfter(lst, _documentRecord.getDocumentAtom());
1013
		}
1014
		ExObjListAtom objAtom = lst.getExObjListAtom();
1015
		// increment the object ID seed
1016
		int objectId = (int) objAtom.getObjectIDSeed() + 1;
1017
		objAtom.setObjectIDSeed(objectId);
1018
1019
		lst.addChildAfter(exObj, objAtom);
1020
		
1021
		return objectId;
1022
	}
1023
1024
    protected int addPersistentObject(PositionDependentRecord slideRecord) {
1025
    	slideRecord.setLastOnDiskOffset(-1);
1026
		_hslfSlideShow.appendRootLevelRecord((Record)slideRecord);
1027
		_records = _hslfSlideShow.getRecords();
1028
1029
        // For position dependent records, hold where they were and now are
1030
        // As we go along, update, and hand over, to any Position Dependent
1031
        //  records we happen across
1032
        Hashtable<Integer,Integer> oldToNewPositions = new Hashtable<Integer,Integer>();
1033
1034
		// Add the new Slide into the PersistPtr stuff
1035
		int slideOffset = 0;
1036
1037
        // First pass - figure out where all the position dependent
1038
        //   records are going to end up, in the new scheme
1039
        // (Annoyingly, some powerpoing files have PersistPtrHolders
1040
        //  that reference slides after the PersistPtrHolder)
1041
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
1042
		for (Record record : _records) {
1043
			if(record instanceof PositionDependentRecord) {
1044
                PositionDependentRecord pdr = (PositionDependentRecord)record;
1045
                int oldPos = pdr.getLastOnDiskOffset();
1046
                int newPos = baos.size();
1047
                pdr.setLastOnDiskOffset(newPos);
1048
                if (record == slideRecord) {
1049
                	// set the slideOffset later, to not interfere with exisiting positions
1050
                	slideOffset = newPos;
1051
                } else {
1052
                	oldToNewPositions.put(Integer.valueOf(oldPos),Integer.valueOf(newPos));
1053
                }
1054
			
1055
			}
1056
			
1057
            // Dummy write out, so the position winds on properly
1058
			try {
1059
				record.writeOut(baos);
1060
			} catch (IOException e) {
1061
				throw new HSLFException(e);
1062
			}
1063
		}
1064
1065
		PersistPtrHolder ptr = null;
1066
		UserEditAtom usr = null;
1067
        // For now, we're only handling PositionDependentRecord's that
1068
        // happen at the top level.
1069
        // In future, we'll need the handle them everywhere, but that's
1070
        // a bit trickier
1071
		for (Record record : _records) {
1072
			if (!(record instanceof PositionDependentRecord)) continue;
1073
1074
			// We've already figured out their new location, and
1075
            // told them that
1076
            // Tell them of the positions of the other records though
1077
            PositionDependentRecord pdr = (PositionDependentRecord)record;
1078
            pdr.updateOtherRecordReferences(oldToNewPositions);
1079
1080
            // Grab interesting records as they come past
1081
			int recordType = (int)record.getRecordType();
1082
            if (recordType == RecordTypes.PersistPtrIncrementalBlock.typeID) {
1083
                ptr = (PersistPtrHolder)record;
1084
            } else if (recordType == RecordTypes.UserEditAtom.typeID) {
1085
                usr = (UserEditAtom)record;
1086
            }
1087
		}
1088
		
1089
		// persist ID is UserEditAtom.maxPersistWritten + 1
1090
		int psrId = usr.getMaxPersistWritten() + 1;
1091
1092
		// Last view is now of the slide
1093
		usr.setLastViewType((short) UserEditAtom.LAST_VIEW_SLIDE_VIEW);
1094
		// increment the number of persistent objects
1095
		usr.setMaxPersistWritten(psrId);
1096
		_hslfSlideShow.getCurrentUserAtom().setCurrentEditOffset(usr.getLastOnDiskOffset());
1097
1098
		// Add the new slide into the last PersistPtr
1099
		// (Also need to tell it where it is)
1100
		slideRecord.setLastOnDiskOffset(slideOffset);
1101
		ptr.addSlideLookup(psrId, slideOffset);
1102
		logger.log(POILogger.INFO, "New slide/object ended up at " + slideOffset);
1103
1104
		return psrId;
1105
    }
1076
}
1106
}
(-)src/scratchpad/testcases/org/apache/poi/hslf/TestReWrite.java (+12 lines)
Lines 160-163 Link Here
160
			assertEquals(_oData[i], _nData[i]);
160
			assertEquals(_oData[i], _nData[i]);
161
		}
161
		}
162
	}
162
	}
163
    
164
    public void test48593() throws Exception {
165
		SlideShow slideShow = new SlideShow();
166
		slideShow.createSlide();
167
		slideShow = HSLFTestDataSamples.writeOutAndReadBack(slideShow);
168
		slideShow.createSlide();
169
		slideShow = HSLFTestDataSamples.writeOutAndReadBack(slideShow);
170
		slideShow.createSlide();
171
		slideShow = HSLFTestDataSamples.writeOutAndReadBack(slideShow);
172
		slideShow.createSlide();
173
		slideShow = HSLFTestDataSamples.writeOutAndReadBack(slideShow);
174
    }
163
}
175
}

Return to bug 48593