1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
|
/* ====================================================================
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.xssf.usermodel;
import java.util.Iterator;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.ss.usermodel.ShapeContainer;
import org.apache.poi.util.Internal;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupTransform2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTConnector;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGroupShape;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGroupShapeNonVisual;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTPicture;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape;
/**
* This object specifies a group shape that represents many shapes grouped together. This shape is to be treated
* just as if it were a regular shape but instead of being described by a single geometry it is made up of all the
* shape geometries encompassed within it. Within a group shape each of the shapes that make up the group are
* specified just as they normally would.
*/
public final class XSSFShapeGroup extends XSSFShape implements ShapeContainer<XSSFShape> {
private static CTGroupShape prototype;
private CTGroupShape ctGroup;
/**
* Construct a new XSSFSimpleShape object.
*
* @param drawing the XSSFDrawing that owns this shape
* @param ctGroup the XML bean that stores this group content
*/
protected XSSFShapeGroup(XSSFDrawing drawing, CTGroupShape ctGroup) {
this.drawing = drawing;
this.ctGroup = ctGroup;
}
/**
* Initialize default structure of a new shape group
*/
protected static CTGroupShape prototype() {
if (prototype == null) {
CTGroupShape shape = CTGroupShape.Factory.newInstance();
CTGroupShapeNonVisual nv = shape.addNewNvGrpSpPr();
CTNonVisualDrawingProps nvpr = nv.addNewCNvPr();
nvpr.setId(0);
nvpr.setName("Group 0");
nv.addNewCNvGrpSpPr();
CTGroupShapeProperties sp = shape.addNewGrpSpPr();
CTGroupTransform2D t2d = sp.addNewXfrm();
CTPositiveSize2D p1 = t2d.addNewExt();
p1.setCx(0);
p1.setCy(0);
CTPoint2D p2 = t2d.addNewOff();
p2.setX(0);
p2.setY(0);
CTPositiveSize2D p3 = t2d.addNewChExt();
p3.setCx(0);
p3.setCy(0);
CTPoint2D p4 = t2d.addNewChOff();
p4.setX(0);
p4.setY(0);
prototype = shape;
}
return prototype;
}
/**
* Constructs a textbox.
*
* @param anchor the child anchor describes how this shape is attached
* to the group.
* @return the newly created textbox.
*/
public XSSFTextBox createTextbox(XSSFChildAnchor anchor){
CTShape ctShape = ctGroup.addNewSp();
ctShape.set(XSSFSimpleShape.prototype());
XSSFTextBox shape = new XSSFTextBox(getDrawing(), ctShape);
shape.parent = this;
shape.anchor = anchor;
shape.setXfrm(anchor.getCTTransform2D());
return shape;
}
/**
* Creates a simple shape. This includes such shapes as lines, rectangles,
* and ovals.
*
* @param anchor the child anchor describes how this shape is attached
* to the group.
* @return the newly created shape.
*/
public XSSFSimpleShape createSimpleShape(XSSFChildAnchor anchor) {
CTShape ctShape = ctGroup.addNewSp();
ctShape.set(XSSFSimpleShape.prototype());
XSSFSimpleShape shape = new XSSFSimpleShape(getDrawing(), ctShape);
shape.parent = this;
shape.anchor = anchor;
shape.setXfrm(anchor.getCTTransform2D());
return shape;
}
/**
* Creates a simple shape. This includes such shapes as lines, rectangles,
* and ovals.
*
* @param anchor the child anchor describes how this shape is attached
* to the group.
* @return the newly created shape.
*/
public XSSFConnector createConnector(XSSFChildAnchor anchor) {
CTConnector ctShape = ctGroup.addNewCxnSp();
ctShape.set(XSSFConnector.prototype());
XSSFConnector shape = new XSSFConnector(getDrawing(), ctShape);
shape.parent = this;
shape.anchor = anchor;
shape.getCTConnector().getSpPr().setXfrm(anchor.getCTTransform2D());
return shape;
}
/**
* Creates a picture.
*
* @param anchor the client anchor describes how this picture is attached to the sheet.
* @param pictureIndex the index of the picture in the workbook collection of pictures,
* {@link XSSFWorkbook#getAllPictures()} .
* @return the newly created picture shape.
*/
public XSSFPicture createPicture(XSSFClientAnchor anchor, int pictureIndex) {
PackageRelationship rel = getDrawing().addPictureReference(pictureIndex);
CTPicture ctShape = ctGroup.addNewPic();
ctShape.set(XSSFPicture.prototype());
XSSFPicture shape = new XSSFPicture(getDrawing(), ctShape);
shape.parent = this;
shape.anchor = anchor;
shape.setPictureReference(rel);
return shape;
}
/**
* Creates a group shape.
*
* @param anchor the client anchor describes how this group is attached to the group.
* @return the newly created group shape.
*/
public XSSFShapeGroup createGroup(XSSFChildAnchor anchor) {
CTGroupShape ctShape = ctGroup.addNewGrpSp();
ctShape.set(prototype());
XSSFShapeGroup shape = new XSSFShapeGroup(getDrawing(), ctShape);
shape.parent = this;
shape.anchor = anchor;
// TODO: calculate bounding rectangle on anchor and set off/ext correctly
CTGroupTransform2D xfrm = shape.getCTGroupShape().getGrpSpPr().getXfrm();
CTTransform2D t2 = anchor.getCTTransform2D();
xfrm.setOff(t2.getOff());
xfrm.setExt(t2.getExt());
// child offset is left to 0,0
xfrm.setChExt(t2.getExt());
xfrm.setFlipH(t2.getFlipH());
xfrm.setFlipV(t2.getFlipV());
return shape;
}
@Internal
public CTGroupShape getCTGroupShape() {
return ctGroup;
}
/**
* Sets the coordinate space of this group. All children are constrained
* to these coordinates.
*/
public void setCoordinates(int x1, int y1, int x2, int y2) {
CTGroupTransform2D t2d = ctGroup.getGrpSpPr().getXfrm();
CTPoint2D off = t2d.getOff();
off.setX(x1);
off.setY(y1);
CTPositiveSize2D ext = t2d.getExt();
ext.setCx(x2);
ext.setCy(y2);
CTPoint2D chOff = t2d.getChOff();
chOff.setX(x1);
chOff.setY(y1);
CTPositiveSize2D chExt = t2d.getChExt();
chExt.setCx(x2);
chExt.setCy(y2);
}
@Override
protected CTShapeProperties getShapeProperties() {
throw new IllegalStateException("Not supported for shape group");
}
@Override
public Iterator<XSSFShape> iterator() {
return getDrawing().getShapes(this).iterator();
}
@Override
public String getShapeName() {
return ctGroup.getNvGrpSpPr().getCNvPr().getName();
}
}
|