blob: 2892e93f0d33a66e7e22459646b8282142d433ce [file] [log] [blame]
/*
* ====================================================================
* 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 javax.xml.namespace.QName;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.util.Internal;
import org.apache.xmlbeans.XmlCursor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObjectData;
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.CTGraphicalObjectFrame;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGraphicalObjectFrameNonVisual;
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* Represents DrawingML GraphicalObjectFrame.
*/
public final class XSSFGraphicFrame extends XSSFShape {
private static CTGraphicalObjectFrame prototype;
private CTGraphicalObjectFrame graphicFrame;
/**
* Construct a new XSSFGraphicFrame object.
*
* @param drawing the XSSFDrawing that owns this frame
* @param ctGraphicFrame the XML bean that stores this frame content
*/
protected XSSFGraphicFrame(XSSFDrawing drawing, CTGraphicalObjectFrame ctGraphicFrame) {
this.drawing = drawing; // protected field on XSSFShape
this.graphicFrame = ctGraphicFrame;
// TODO: there may be a better way to delegate this
CTGraphicalObjectData graphicData = graphicFrame.getGraphic().getGraphicData();
if (graphicData != null) {
NodeList nodes = graphicData.getDomNode().getChildNodes();
for (int i = 0; i < nodes.getLength(); i++) {
final Node node = nodes.item(i);
// if the frame references a chart, associate the chart with this instance
if (node.getNodeName().equals("c:chart")) {
// this better succeed or the document is invalid
POIXMLDocumentPart relation = drawing.getRelationById(node.getAttributes().getNamedItem("r:id").getNodeValue());
// Do XWPF charts need similar treatment?
if (relation instanceof XSSFChart) {
((XSSFChart) relation).setGraphicFrame(this);
}
}
}
}
}
@Internal
public CTGraphicalObjectFrame getCTGraphicalObjectFrame() {
return graphicFrame;
}
/**
* Initialize default structure of a new graphic frame
*/
protected static CTGraphicalObjectFrame prototype() {
if (prototype == null) {
CTGraphicalObjectFrame graphicFrame = CTGraphicalObjectFrame.Factory.newInstance();
CTGraphicalObjectFrameNonVisual nvGraphic = graphicFrame.addNewNvGraphicFramePr();
CTNonVisualDrawingProps props = nvGraphic.addNewCNvPr();
props.setId(0);
props.setName("Diagramm 1");
nvGraphic.addNewCNvGraphicFramePr();
CTTransform2D transform = graphicFrame.addNewXfrm();
CTPositiveSize2D extPoint = transform.addNewExt();
CTPoint2D offPoint = transform.addNewOff();
extPoint.setCx(0);
extPoint.setCy(0);
offPoint.setX(0);
offPoint.setY(0);
/* CTGraphicalObject graphic = */ graphicFrame.addNewGraphic();
prototype = graphicFrame;
}
return prototype;
}
/**
* Sets the frame macro.
*/
public void setMacro(String macro) {
graphicFrame.setMacro(macro);
}
/**
* Sets the frame name.
*/
public void setName(String name) {
getNonVisualProperties().setName(name);
}
/**
* Returns the frame name.
* @return name of the frame
*/
public String getName() {
return getNonVisualProperties().getName();
}
private CTNonVisualDrawingProps getNonVisualProperties() {
CTGraphicalObjectFrameNonVisual nvGraphic = graphicFrame.getNvGraphicFramePr();
return nvGraphic.getCNvPr();
}
/**
* Attaches frame to an anchor.
*/
protected void setAnchor(XSSFClientAnchor anchor) {
this.anchor = anchor;
}
/**
* Returns the frame anchor.
* @return the XSSFClientAnchor anchor this frame is attached to
*/
public XSSFClientAnchor getAnchor() {
return (XSSFClientAnchor) anchor;
}
/**
* Assign a DrawingML chart to the graphic frame.
*/
protected void setChart(XSSFChart chart, String relId) {
CTGraphicalObjectData data = graphicFrame.getGraphic().addNewGraphicData();
appendChartElement(data, relId);
chart.setGraphicFrame(this);
}
/**
* Gets the frame id.
*/
public long getId() {
return graphicFrame.getNvGraphicFramePr().getCNvPr().getId();
}
/**
* Sets the frame id.
*/
protected void setId(long id) {
graphicFrame.getNvGraphicFramePr().getCNvPr().setId(id);
}
/**
* The low level code to insert {@code <c:chart>} tag into
* {@code<a:graphicData>}.
*
* Here is the schema (ECMA-376):
* <pre>
* {@code
* <complexType name="CT_GraphicalObjectData">
* <sequence>
* <any minOccurs="0" maxOccurs="unbounded" processContents="strict"/>
* </sequence>
* <attribute name="uri" type="xsd:token"/>
* </complexType>
* }
* </pre>
*/
private void appendChartElement(CTGraphicalObjectData data, String id) {
String r_namespaceUri = STRelationshipId.type.getName().getNamespaceURI();
String c_namespaceUri = XSSFDrawing.NAMESPACE_C;
XmlCursor cursor = data.newCursor();
cursor.toNextToken();
cursor.beginElement(new QName(c_namespaceUri, "chart", "c"));
cursor.insertAttributeWithValue(new QName(r_namespaceUri, "id", "r"), id);
cursor.dispose();
data.setUri(c_namespaceUri);
}
@Override
protected CTShapeProperties getShapeProperties(){
return null;
}
@Override
public String getShapeName() {
return graphicFrame.getNvGraphicFramePr().getCNvPr().getName();
}
}