[bug-69669] try to share some code between the old code that I brought back and the newer code that caused the problems

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1925872 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
PJ Fanning 2025-05-27 18:48:31 +00:00
parent d189f69333
commit 16b53a8bc7
3 changed files with 94 additions and 76 deletions

View File

@ -47,6 +47,68 @@ import org.apache.poi.util.LocaleUtil;
* @since POI 4.0.0
*/
public class HSLFShapePlaceholderDetails extends HSLFPlaceholderDetails {
static void updateSPRecord(final HSLFSimpleShape shape, final Placeholder placeholder) {
final EscherSpRecord spRecord = shape.getEscherChild(EscherSpRecord.RECORD_ID);
int flags = spRecord.getFlags();
if (placeholder == null) {
flags ^= EscherSpRecord.FLAG_HAVEMASTER;
} else {
flags |= EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HAVEMASTER;
}
spRecord.setFlags(flags);
// Placeholders can't be grouped
shape.setEscherProperty(EscherPropertyTypes.PROTECTION__LOCKAGAINSTGROUPING, (placeholder == null ? -1 : 262144));
}
static void removePlaceholder(final HSLFSimpleShape shape) {
final HSLFEscherClientDataRecord clientData = shape.getClientData(false);
if (clientData != null) {
clientData.removeChild(OEPlaceholderAtom.class);
clientData.removeChild(RoundTripHFPlaceholder12.class);
// remove client data if the placeholder was the only child to be carried
if (clientData.getChildRecords().isEmpty()) {
shape.getSpContainer().removeChildRecord(clientData);
}
}
}
static OEPlaceholderAtom createOEPlaceholderAtom(final HSLFEscherClientDataRecord clientData) {
return createOEPlaceholderAtom(clientData, (byte) 0);
}
static OEPlaceholderAtom createOEPlaceholderAtom(final HSLFEscherClientDataRecord clientData,
final byte placeholderId) {
OEPlaceholderAtom oePlaceholderAtom = new OEPlaceholderAtom();
oePlaceholderAtom.setPlaceholderSize((byte)OEPlaceholderAtom.PLACEHOLDER_FULLSIZE);
// TODO: placement id only "SHOULD" be unique ... check other placeholders on sheet for unique id
oePlaceholderAtom.setPlacementId(-1);
oePlaceholderAtom.setPlaceholderId(placeholderId);
clientData.addChild(oePlaceholderAtom);
return oePlaceholderAtom;
}
static byte getPlaceholderId(final HSLFSheet sheet, final Placeholder placeholder) {
if (placeholder == null) {
return 0;
}
byte phId;
// TODO: implement/switch NotesMaster
if (sheet instanceof HSLFSlideMaster) {
phId = (byte) placeholder.nativeSlideMasterId;
} else if (sheet instanceof HSLFNotes) {
phId = (byte) placeholder.nativeNotesId;
} else {
phId = (byte) placeholder.nativeSlideId;
}
if (phId == -2) {
throw new HSLFException("Placeholder " + placeholder.name() + " not supported for this sheet type (" + sheet.getClass() + ")");
}
return phId;
}
private enum PlaceholderContainer {
slide, master, notes, notesMaster
}
@ -78,7 +140,7 @@ public class HSLFShapePlaceholderDetails extends HSLFPlaceholderDetails {
@Override
public Placeholder getPlaceholder() {
updatePlaceholderAtom(false);
updatePlaceholderAtom(null, false);
final int phId;
if (oePlaceholderAtom != null) {
phId = oePlaceholderAtom.getPlaceholderId();
@ -105,17 +167,7 @@ public class HSLFShapePlaceholderDetails extends HSLFPlaceholderDetails {
@Override
public void setPlaceholder(final Placeholder placeholder) {
final EscherSpRecord spRecord = shape.getEscherChild(EscherSpRecord.RECORD_ID);
int flags = spRecord.getFlags();
if (placeholder == null) {
flags ^= EscherSpRecord.FLAG_HAVEMASTER;
} else {
flags |= EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HAVEMASTER;
}
spRecord.setFlags(flags);
// Placeholders can't be grouped
shape.setEscherProperty(EscherPropertyTypes.PROTECTION__LOCKAGAINSTGROUPING, (placeholder == null ? -1 : 262144));
updateSPRecord(shape, placeholder);
if (placeholder == null) {
removePlaceholder();
@ -123,7 +175,7 @@ public class HSLFShapePlaceholderDetails extends HSLFPlaceholderDetails {
}
// init client data
updatePlaceholderAtom(true);
updatePlaceholderAtom(placeholder, true);
final byte phId = getPlaceholderId(placeholder);
oePlaceholderAtom.setPlaceholderId(phId);
@ -158,7 +210,7 @@ public class HSLFShapePlaceholderDetails extends HSLFPlaceholderDetails {
if (ph == null || size == null) {
return;
}
updatePlaceholderAtom(true);
updatePlaceholderAtom(ph, true);
final byte ph_size;
switch (size) {
@ -209,20 +261,12 @@ public class HSLFShapePlaceholderDetails extends HSLFPlaceholderDetails {
}
private void removePlaceholder() {
final HSLFEscherClientDataRecord clientData = shape.getClientData(false);
if (clientData != null) {
clientData.removeChild(OEPlaceholderAtom.class);
clientData.removeChild(RoundTripHFPlaceholder12.class);
// remove client data if the placeholder was the only child to be carried
if (clientData.getChildRecords().isEmpty()) {
shape.getSpContainer().removeChildRecord(clientData);
}
}
removePlaceholder(shape);
oePlaceholderAtom = null;
roundTripHFPlaceholder12 = null;
}
private void updatePlaceholderAtom(final boolean create) {
private void updatePlaceholderAtom(final Placeholder placeholder, final boolean create) {
localDateTime = null;
if (shape instanceof HSLFTextBox) {
EscherTextboxWrapper txtBox = ((HSLFTextBox)shape).getEscherTextboxWrapper();
@ -255,11 +299,8 @@ public class HSLFShapePlaceholderDetails extends HSLFPlaceholderDetails {
}
if (oePlaceholderAtom == null) {
oePlaceholderAtom = new OEPlaceholderAtom();
oePlaceholderAtom.setPlaceholderSize((byte)OEPlaceholderAtom.PLACEHOLDER_FULLSIZE);
// TODO: placement id only "SHOULD" be unique ... check other placeholders on sheet for unique id
oePlaceholderAtom.setPlacementId(-1);
clientData.addChild(oePlaceholderAtom);
final byte phId = getPlaceholderId(shape.getSheet(), placeholder);
oePlaceholderAtom = createOEPlaceholderAtom(clientData, phId);
}
if (roundTripHFPlaceholder12 == null) {
roundTripHFPlaceholder12 = new RoundTripHFPlaceholder12();

View File

@ -56,6 +56,11 @@ import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.Units;
import static org.apache.poi.hslf.usermodel.HSLFShapePlaceholderDetails.createOEPlaceholderAtom;
import static org.apache.poi.hslf.usermodel.HSLFShapePlaceholderDetails.getPlaceholderId;
import static org.apache.poi.hslf.usermodel.HSLFShapePlaceholderDetails.removePlaceholder;
import static org.apache.poi.hslf.usermodel.HSLFShapePlaceholderDetails.updateSPRecord;
/**
* An abstract simple (non-group) shape.
* This is the parent class for all primitive shapes like Line, Rectangle, etc.
@ -582,45 +587,25 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
@Override
public void setPlaceholder(Placeholder placeholder) {
EscherSpRecord spRecord = getEscherChild(EscherSpRecord.RECORD_ID);
int flags = spRecord.getFlags();
if (placeholder == null) {
flags ^= EscherSpRecord.FLAG_HAVEMASTER;
} else {
flags |= EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HAVEMASTER;
}
spRecord.setFlags(flags);
updateSPRecord(this, placeholder);
// Placeholders can't be grouped
setEscherProperty(EscherPropertyTypes.PROTECTION__LOCKAGAINSTGROUPING, (placeholder == null ? -1 : 262144));
HSLFEscherClientDataRecord clientData = getClientData(false);
if (placeholder == null) {
if (clientData != null) {
clientData.removeChild(OEPlaceholderAtom.class);
clientData.removeChild(RoundTripHFPlaceholder12.class);
// remove client data if the placeholder was the only child to be carried
if (clientData.getChildRecords().isEmpty()) {
getSpContainer().removeChildRecord(clientData);
}
}
removePlaceholder(this);
return;
}
if (clientData == null) {
clientData = getClientData(true);
}
HSLFEscherClientDataRecord clientData = getClientData(true);
// OEPlaceholderAtom tells powerpoint that this shape is a placeholder
OEPlaceholderAtom oep = null;
RoundTripHFPlaceholder12 rtp = null;
for (org.apache.poi.hslf.record.Record r : clientData.getHSLFChildRecords()) {
if (r instanceof OEPlaceholderAtom) {
oep = (OEPlaceholderAtom)r;
oep = (OEPlaceholderAtom) r;
break;
}
if (r instanceof RoundTripHFPlaceholder12) {
rtp = (RoundTripHFPlaceholder12)r;
rtp = (RoundTripHFPlaceholder12) r;
break;
}
}
@ -632,20 +617,7 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
* This occurs when the user has moved the placeholder from its original position.
* In this case the placeholder ID is -1.
*/
byte phId;
HSLFSheet sheet = getSheet();
// TODO: implement/switch NotesMaster
if (sheet instanceof HSLFSlideMaster) {
phId = (byte)placeholder.nativeSlideMasterId;
} else if (sheet instanceof HSLFNotes) {
phId = (byte)placeholder.nativeNotesId;
} else {
phId = (byte)placeholder.nativeSlideId;
}
if (phId == -2) {
throw new HSLFException("Placeholder "+placeholder.name()+" not supported for this sheet type ("+sheet.getClass()+")");
}
final byte phId = getPlaceholderId(getSheet(), placeholder);
switch (placeholder) {
case HEADER:
@ -664,19 +636,16 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H
clientData.removeChild(RoundTripHFPlaceholder12.class);
}
if (oep == null) {
oep = new OEPlaceholderAtom();
oep.setPlaceholderSize((byte)OEPlaceholderAtom.PLACEHOLDER_FULLSIZE);
// TODO: placement id only "SHOULD" be unique ... check other placeholders on sheet for unique id
oep.setPlacementId(-1);
oep.setPlaceholderId(phId);
clientData.addChild(oep);
oep = createOEPlaceholderAtom(clientData, phId);
}
break;
}
// reverted this call because of https://bz.apache.org/bugzilla/show_bug.cgi?id=69669
//getPlaceholderDetails().setPlaceholder(placeholder);
}
// reset the placeholder details so that the next call to getPlaceholderDetails() will reinitialize it
_placeholderDetails = null;
}
@Override
public void setStrokeStyle(Object... styles) {

View File

@ -18,6 +18,8 @@
package org.apache.poi.hslf.model;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import java.awt.Color;
import java.awt.Rectangle;
@ -27,9 +29,11 @@ import java.util.Arrays;
import org.apache.poi.hslf.HSLFTestDataSamples;
import org.apache.poi.hslf.usermodel.HSLFLine;
import org.apache.poi.hslf.usermodel.HSLFPlaceholder;
import org.apache.poi.hslf.usermodel.HSLFShape;
import org.apache.poi.hslf.usermodel.HSLFSlide;
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
import org.apache.poi.hslf.usermodel.HSLFTextBox;
import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound;
import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
import org.junit.jupiter.api.Test;
@ -65,7 +69,11 @@ public final class TestLine {
final String title = "Lines tester";
try (HSLFSlideShow ppt1 = new HSLFSlideShow()) {
HSLFSlide slide1 = ppt1.createSlide();
slide1.addTitle().setText(title);
HSLFTextBox titleBox = slide1.addTitle();
titleBox.setText(title);
assertInstanceOf(HSLFPlaceholder.class, titleBox);
HSLFPlaceholder pl = (HSLFPlaceholder) titleBox;
assertNotNull(pl.getPlaceholder());
for (Object[] line : lines) {
HSLFLine hslfLine = new HSLFLine();