All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.odftoolkit.odfdom.doc.OdfPresentationDocument Maven / Gradle / Ivy

Go to download

ODFDOM is an OpenDocument Format (ODF) framework. Its purpose is to provide an easy common way to create, access and manipulate ODF files, without requiring detailed knowledge of the ODF specification. It is designed to provide the ODF developer community with an easy lightwork programming API portable to any object-oriented language. The current reference implementation is written in Java.

There is a newer version: 1.0.0-BETA1
Show newest version
/**
 * **********************************************************************
 *
 * 

DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * *

Copyright 2008, 2010 Oracle and/or its affiliates. All rights reserved. * *

Use is subject to license terms. * *

Licensed 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. You can also obtain a copy of the License at * http://odftoolkit.org/docs/license.txt * *

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.odftoolkit.odfdom.doc; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.StringTokenizer; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; import org.odftoolkit.odfdom.doc.presentation.OdfSlide; import org.odftoolkit.odfdom.dom.OdfContentDom; import org.odftoolkit.odfdom.dom.OdfDocumentNamespace; import org.odftoolkit.odfdom.dom.OdfStylesDom; import org.odftoolkit.odfdom.dom.attribute.presentation.PresentationClassAttribute; import org.odftoolkit.odfdom.dom.element.OdfStyleBase; import org.odftoolkit.odfdom.dom.element.draw.DrawFrameElement; import org.odftoolkit.odfdom.dom.element.draw.DrawPageElement; import org.odftoolkit.odfdom.dom.element.draw.DrawPageThumbnailElement; import org.odftoolkit.odfdom.dom.element.office.OfficePresentationElement; import org.odftoolkit.odfdom.dom.element.presentation.PresentationNotesElement; import org.odftoolkit.odfdom.dom.element.style.StyleGraphicPropertiesElement; import org.odftoolkit.odfdom.dom.element.style.StylePresentationPageLayoutElement; import org.odftoolkit.odfdom.incubator.doc.office.OdfOfficeAutomaticStyles; import org.odftoolkit.odfdom.incubator.doc.office.OdfOfficeStyles; import org.odftoolkit.odfdom.pkg.MediaType; import org.odftoolkit.odfdom.pkg.OdfElement; import org.odftoolkit.odfdom.pkg.OdfFileDom; import org.odftoolkit.odfdom.pkg.OdfName; import org.odftoolkit.odfdom.pkg.OdfNamespace; import org.odftoolkit.odfdom.pkg.OdfPackage; import org.odftoolkit.odfdom.pkg.OdfPackageDocument; import org.odftoolkit.odfdom.pkg.manifest.OdfFileEntry; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** This class represents an empty ODF presentation. */ public class OdfPresentationDocument extends OdfDocument { private static final String EMPTY_PRESENTATION_DOCUMENT_PATH = "/OdfPresentationDocument.odp"; static final Resource EMPTY_PRESENTATION_DOCUMENT_RESOURCE = new Resource(EMPTY_PRESENTATION_DOCUMENT_PATH); /** This enum contains all possible media types of OdfPresentationDocument documents. */ public enum OdfMediaType implements MediaType { PRESENTATION(OdfDocument.OdfMediaType.PRESENTATION), PRESENTATION_TEMPLATE(OdfDocument.OdfMediaType.PRESENTATION_TEMPLATE); private final OdfDocument.OdfMediaType mMediaType; OdfMediaType(OdfDocument.OdfMediaType mediaType) { this.mMediaType = mediaType; } /** @return the ODF mediatype of this document */ public OdfDocument.OdfMediaType getOdfMediaType() { return mMediaType; } /** @return the mediatype of this document */ public String getMediaTypeString() { return mMediaType.getMediaTypeString(); } /** @return the ODF filesuffix of this document */ public String getSuffix() { return mMediaType.getSuffix(); } /** * @param mediaType string defining an ODF document * @return the according OdfMediatype encapuslating the given string and the suffix */ public static OdfDocument.OdfMediaType getOdfMediaType(String mediaType) { return OdfDocument.OdfMediaType.getOdfMediaType(mediaType); } } /** * Creates an empty presentation document. * * @return ODF presentation document based on a default template * @throws java.lang.Exception - if the document could not be created */ public static OdfPresentationDocument newPresentationDocument() throws Exception { return (OdfPresentationDocument) OdfDocument.loadTemplate( EMPTY_PRESENTATION_DOCUMENT_RESOURCE, OdfDocument.OdfMediaType.PRESENTATION); } /** * Creates an empty presentation template. * * @return ODF presentation template based on a default * @throws Exception - if the template could not be created */ public static OdfPresentationDocument newPresentationTemplateDocument() throws Exception { OdfPresentationDocument doc = (OdfPresentationDocument) OdfDocument.loadTemplate( EMPTY_PRESENTATION_DOCUMENT_RESOURCE, OdfDocument.OdfMediaType.PRESENTATION_TEMPLATE); doc.changeMode(OdfMediaType.PRESENTATION_TEMPLATE); return doc; } /** * To avoid data duplication a new document is only created, if not already opened. A document is * cached by this constructor using the internalpath as key. */ protected OdfPresentationDocument( OdfPackage pkg, String internalPath, OdfPresentationDocument.OdfMediaType odfMediaType) throws SAXException { super(pkg, internalPath, odfMediaType.mMediaType); } /** * Creates an OdfPresentationDocument from the OpenDocument provided by a resource Stream. * *

Since an InputStream does not provide the arbitrary (non sequentiell) read access needed by * OdfPresentationDocument, the InputStream is cached. This usually takes more time compared to * the other createInternalDocument methods. An advantage of caching is that there are no problems * overwriting an input file. * *

If the resource stream is not a ODF presentation document, ClassCastException might be * thrown. * * @param inputStream - the InputStream of the ODF presentation document. * @return the presentation document created from the given InputStream * @throws java.lang.Exception - if the document could not be created. */ public static OdfPresentationDocument loadDocument(InputStream inputStream) throws Exception { return (OdfPresentationDocument) OdfDocument.loadDocument(inputStream); } /** * Loads an OdfPresentationDocument from the provided path. * *

OdfPresentationDocument relies on the file being available for read access over the whole * lifecycle of OdfPresentationDocument. * *

If the resource stream is not a ODF presentation document, ClassCastException might be * thrown. * * @param documentPath - the path from where the document can be loaded * @return the presentation document from the given path or NULL if the media type is not * supported by ODFDOM. * @throws java.lang.Exception - if the document could not be created. */ public static OdfPresentationDocument loadDocument(String documentPath) throws Exception { return (OdfPresentationDocument) OdfDocument.loadDocument(documentPath); } /** * Creates an OdfPresentationDocument from the OpenDocument provided by a File. * *

OdfPresentationDocument relies on the file being available for read access over the whole * lifecycle of OdfPresentationDocument. * *

If the resource stream is not a ODF presentation document, ClassCastException might be * thrown. * * @param file - a file representing the ODF presentation document. * @return the presentation document created from the given File * @throws java.lang.Exception - if the document could not be created. */ public static OdfPresentationDocument loadDocument(File file) throws Exception { return (OdfPresentationDocument) OdfDocument.loadDocument(file); } /** * Get the content root of a presentation document. * * @return content root, representing the office:presentation tag * @throws Exception if the file DOM could not be created. */ @Override public OfficePresentationElement getContentRoot() throws Exception { return super.getContentRoot(OfficePresentationElement.class); } /** * Switches this instance to the given type. This method can be used to e.g. convert a document * instance to a template and vice versa. Changes take affect in the package when saving the * document. * * @param type the compatible ODF mediatype. */ public void changeMode(OdfMediaType type) { setOdfMediaType(type.mMediaType); } private boolean hasCheckSlideName = false; // if the copy foreign slide for several times, // the same style might be copied for several times with the different name // so use styleRenameMap to keep track the renamed style so we can reuse the style, // rather than new several styles which only have the different style names. // while if the style elements really have the same style name but with different content // such as that these style elements are from different document // so the value for each key should be a list private HashMap> styleRenameMap = new HashMap>(); // the map is used to record if the renamed style name is appended to the current dom private HashMap styleAppendMap = new HashMap(); // the object rename map for image. // can not easily recognize if the embedded document are the same. // private HashMap objectRenameMap = new HashMap(); /** * Return the slide at a specified position in this presentation. Return null if the index is out * of range. * * @param index the index of the slide to be returned * @return a draw slide at the specified position */ public OdfSlide getSlideByIndex(int index) { checkAllSlideName(); OfficePresentationElement contentRoot = null; try { contentRoot = getContentRoot(); } catch (Exception e) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, e); return null; } NodeList slideNodes = contentRoot.getElementsByTagNameNS(OdfDocumentNamespace.DRAW.getUri(), "page"); if ((index >= slideNodes.getLength()) || (index < 0)) { return null; } DrawPageElement slideElement = (DrawPageElement) slideNodes.item(index); return OdfSlide.getInstance(slideElement); } /** * Get the number of the slides in this presentation. * * @return the number of slides */ public int getSlideCount() { checkAllSlideName(); OfficePresentationElement contentRoot = null; try { contentRoot = getContentRoot(); } catch (Exception e) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, e); return 0; } NodeList slideNodes = contentRoot.getElementsByTagNameNS(OdfDocumentNamespace.DRAW.getUri(), "page"); return slideNodes.getLength(); } /** * Return the slide which have a specified slide name in this presentation. * *

According to the odf specification "The draw:name attribute specifies a name by which this * element can be referenced. It is optional but if present, must be unique within the document * instance. If not present, an application may generate a unique name." * *

If the name is null, then return null because all the slide must has its own unique name. * * @param name the specified slide name * @return the slide whose name equals to the specified name */ public OdfSlide getSlideByName(String name) { checkAllSlideName(); if (name == null) { return null; } OfficePresentationElement contentRoot = null; try { contentRoot = getContentRoot(); } catch (Exception e) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, e); return null; } NodeList slideNodes = contentRoot.getElementsByTagNameNS(OdfDocumentNamespace.DRAW.getUri(), "page"); for (int i = 0; i < slideNodes.getLength(); i++) { DrawPageElement slideElement = (DrawPageElement) slideNodes.item(i); OdfSlide slide = OdfSlide.getInstance(slideElement); String slideName = slide.getSlideName(); if (slideName.equals(name)) { return slide; } } return null; } // when access slide related method, this function should be called private void checkAllSlideName() { // check if this function is called or not if (hasCheckSlideName) { return; } List slideNameList = new ArrayList(); OfficePresentationElement contentRoot = null; try { contentRoot = getContentRoot(); } catch (Exception e) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, e); return; } NodeList slideNodes = contentRoot.getElementsByTagNameNS(OdfDocumentNamespace.DRAW.getUri(), "page"); for (int i = 0; i < slideNodes.getLength(); i++) { DrawPageElement slideElement = (DrawPageElement) slideNodes.item(i); String slideName = slideElement.getDrawNameAttribute(); if ((slideName == null) || slideNameList.contains(slideName)) { slideName = "page" + (i + 1) + "-" + makeUniqueName(); slideElement.setDrawNameAttribute(slideName); } slideNameList.add(slideName); } hasCheckSlideName = true; } /** * Return a list iterator containing all slides in this presentation. * * @return a list iterator containing all slides in this presentation */ public Iterator getSlides() { checkAllSlideName(); OfficePresentationElement contentRoot = null; try { contentRoot = getContentRoot(); } catch (Exception e) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, e); return null; } ArrayList slideList = new ArrayList(); NodeList slideNodes = contentRoot.getElementsByTagNameNS(OdfDocumentNamespace.DRAW.getUri(), "page"); for (int i = 0; i < slideNodes.getLength(); i++) { DrawPageElement slideElement = (DrawPageElement) slideNodes.item(i); slideList.add(OdfSlide.getInstance(slideElement)); } return slideList.iterator(); } /** * Delete the slide at a specified position in this presentation. * * @param index the index of the slide that need to be delete *

Throw IndexOutOfBoundsException if the slide index is out of the presentation document * slide count. * @return false if the operation was not successful */ public boolean deleteSlideByIndex(int index) { boolean success = true; checkAllSlideName(); OfficePresentationElement contentRoot = null; try { contentRoot = getContentRoot(); } catch (Exception e) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, e); success = false; return success; } NodeList slideNodes = contentRoot.getElementsByTagNameNS(OdfDocumentNamespace.DRAW.getUri(), "page"); if ((index >= slideNodes.getLength()) || (index < 0)) { throw new IndexOutOfBoundsException( "the specified Index is out of slide count when call deleteSlideByIndex method."); } DrawPageElement slideElement = (DrawPageElement) slideNodes.item(index); // remove all the content of the current page // 1. the reference of the path that contained in this slide is 1, then remove it success &= deleteLinkRef(slideElement); // 2.the reference of the style is 1, then remove it // in order to save time, do not delete the style here success &= deleteStyleRef(slideElement); // remove the current page element contentRoot.removeChild(slideElement); adjustNotePageNumber(index); return success; } private boolean deleteStyleRef(DrawPageElement slideEle) { boolean success = true; try { // method 1: // 1.1. iterate child element of the content element // 1.2. if the child element is an OdfStylableElement, get the style-name ref count //////////////// // method 2: // 2.1. get the list of the style definition ArrayList removeStyles = new ArrayList(); OdfOfficeAutomaticStyles autoStyles = getContentDom().getAutomaticStyles(); NodeList stylesList = autoStyles.getChildNodes(); OdfContentDom contentDom = getContentDom(); XPath xpath = contentDom.getXPath(); // 2.2. get the reference of each style which occurred in the current page for (int i = 0; i < stylesList.getLength(); i++) { Node item = stylesList.item(i); if (item instanceof OdfElement) { OdfElement node = (OdfElement) item; String styleName = node.getAttributeNS(OdfDocumentNamespace.STYLE.getUri(), "name"); if (styleName != null) { // search the styleName contained at the current page element NodeList styleNodes = (NodeList) xpath.evaluate( "//*[@*='" + styleName + "']", contentDom, XPathConstants.NODESET); int styleCnt = styleNodes.getLength(); if (styleCnt > 1) { // the first styleName is occurred in the style definition // so check if the second styleName and last styleName is occurred in the current page // element // if yes, then remove it OdfElement elementFirst = (OdfElement) styleNodes.item(1); OdfElement elementLast = (OdfElement) styleNodes.item(styleCnt - 1); boolean isSamePage = false; if (elementFirst instanceof DrawPageElement) { DrawPageElement tempPage = (DrawPageElement) elementFirst; if (tempPage.equals(slideEle)) { isSamePage = true; } } int relationFirst = slideEle.compareDocumentPosition(elementFirst); int relationLast = slideEle.compareDocumentPosition(elementLast); // if slide element contains the child element which has the styleName reference if (((relationFirst & Node.DOCUMENT_POSITION_CONTAINED_BY) > 0 && (relationLast & Node.DOCUMENT_POSITION_CONTAINED_BY) > 0) || (isSamePage && (styleCnt == 1))) { if (node instanceof OdfStyleBase) { removeStyles.add(node); } } } else { continue; } } } } for (int i = 0; i < removeStyles.size(); i++) { autoStyles.removeChild(removeStyles.get(i)); } } catch (Exception e) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, e); success = false; } return success; } // delete all the xlink:href object which is contained in slideElement and does not referred by // other slides private boolean deleteLinkRef(DrawPageElement slideEle) { boolean success = true; try { OdfContentDom contentDom = getContentDom(); XPath xpath = contentDom.getXPath(); NodeList linkNodes = (NodeList) xpath.evaluate("//*[@xlink:href]", contentDom, XPathConstants.NODESET); for (int i = 0; i < linkNodes.getLength(); i++) { OdfElement object = (OdfElement) linkNodes.item(i); String refObjPath = object.getAttributeNS(OdfDocumentNamespace.XLINK.getUri(), "href"); int relation = slideEle.compareDocumentPosition(object); // if slide element contains the returned element which has the xlink:href reference if ((relation & Node.DOCUMENT_POSITION_CONTAINED_BY) > 0 && refObjPath != null && refObjPath.length() > 0) { // the path of the object is start with "./" NodeList pathNodes = (NodeList) xpath.evaluate( "//*[@xlink:href='" + refObjPath + "']", getContentDom(), XPathConstants.NODESET); int refCount = pathNodes.getLength(); if (refCount == 1) { // delete "./" if (refObjPath.startsWith("./")) { refObjPath = refObjPath.substring(2); } // check if the current document contains the same path OdfFileEntry fileEntry = getPackage().getFileEntry(refObjPath); if (fileEntry != null) { // it is a stream, such as image, binary file getPackage().remove(refObjPath); } else { // note: if refObjPath is a directory, it must end with '/' fileEntry = getPackage().getFileEntry(refObjPath + "/"); removeDocument(refObjPath); } } } } } catch (XPathExpressionException e) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, e); success = false; } catch (Exception e) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, e); success = false; } return success; } /** * Delete all the slides with a specified name in this presentation. * * @param name the name of the slide that need to be delete * @return false if the operation was not successful */ public boolean deleteSlideByName(String name) { boolean success = true; checkAllSlideName(); OfficePresentationElement contentRoot = null; try { contentRoot = getContentRoot(); } catch (Exception e) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, e); success = false; return success; } OdfSlide slide = getSlideByName(name); DrawPageElement slideElement = slide.getOdfElement(); // remove all the content of the current page // 1. the reference of the path that contained in this slide is 1, then remove its success &= deleteLinkRef(slideElement); // 2.the reference of the style is 1, then remove it // in order to save time, do not delete style here success &= deleteStyleRef(slideElement); // remove the current page element contentRoot.removeChild(slideElement); adjustNotePageNumber(0); return success; } /** * Make a copy of the slide at a specified position to another position in this presentation. The * original slide which at the dest index and after the dest index will move after. * *

* * @param source the source position of the slide need to be copied * @param dest the destination position of the slide need to be copied * @param newName the new name of the copied slide * @return the new slide at the destination position with the specified name, and it has the same * content with the slide at the source position. *

Throw IndexOutOfBoundsException if the slide index is out of the presentation document * slide count. If copy the slide at the end of document, destIndex should set the same value * with the slide count. */ public OdfSlide copySlide(int source, int dest, String newName) { checkAllSlideName(); OfficePresentationElement contentRoot = null; try { contentRoot = getContentRoot(); } catch (Exception e) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, e); return null; } NodeList slideList = contentRoot.getElementsByTagNameNS(OdfDocumentNamespace.DRAW.getUri(), "page"); int slideCount = slideList.getLength(); if ((source < 0) || (source >= slideCount) || (dest < 0) || (dest > slideCount)) { throw new IndexOutOfBoundsException( "the specified Index is out of slide count when call copySlide method."); } DrawPageElement sourceSlideElement = (DrawPageElement) slideList.item(source); DrawPageElement cloneSlideElement = (DrawPageElement) sourceSlideElement.cloneNode(true); cloneSlideElement.setDrawNameAttribute(newName); if (dest == slideCount) { contentRoot.appendChild(cloneSlideElement); } else { DrawPageElement refSlide = (DrawPageElement) slideList.item(dest); contentRoot.insertBefore(cloneSlideElement, refSlide); } adjustNotePageNumber(Math.min(source, dest)); // in case that the appended new slide have the same name with the original slide hasCheckSlideName = false; checkAllSlideName(); return OdfSlide.getInstance(cloneSlideElement); } /** * Move the slide at a specified position to the destination position. * * @param source the current index of the slide that need to be moved * @param dest The index of the destination position before the move action *

Throw IndexOutOfBoundsException if the slide index is out of the presentation document * slide count. */ public void moveSlide(int source, int dest) { checkAllSlideName(); OfficePresentationElement contentRoot = null; try { contentRoot = getContentRoot(); } catch (Exception e) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, e); return; } NodeList slideList = contentRoot.getElementsByTagNameNS(OdfDocumentNamespace.DRAW.getUri(), "page"); int slideCount = slideList.getLength(); if ((source < 0) || (source >= slideCount) || (dest < 0) || (dest > slideCount)) { throw new IndexOutOfBoundsException( "the specified Index is out of slide count when call moveSlide method."); } DrawPageElement sourceSlide = (DrawPageElement) slideList.item(source); if (dest == slideCount) { contentRoot.appendChild(sourceSlide); } else { DrawPageElement refSlide = (DrawPageElement) slideList.item(dest); contentRoot.insertBefore(sourceSlide, refSlide); } adjustNotePageNumber(Math.min(source, dest)); } /** * Append all the slides of the specified presentation document to the current document. * * @param srcDoc the specified OdfPresentationDocument that need to be appended */ public void appendPresentation(OdfPresentationDocument srcDoc) { checkAllSlideName(); OfficePresentationElement contentRoot = null; OdfFileDom contentDom = null; OfficePresentationElement srcContentRoot = null; try { contentRoot = getContentRoot(); contentDom = getContentDom(); srcContentRoot = srcDoc.getContentRoot(); } catch (Exception e) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, e); } NodeList slideList = contentRoot.getElementsByTagNameNS(OdfDocumentNamespace.DRAW.getUri(), "page"); int slideNum = slideList.getLength(); // clone the srcContentRoot, and make a modification on this clone node. OfficePresentationElement srcCloneContentRoot = (OfficePresentationElement) srcContentRoot.cloneNode(true); // copy all the referred xlink:href here copyForeignLinkRef(srcCloneContentRoot); // copy all the referred style definition here copyForeignStyleRef(srcCloneContentRoot, srcDoc); Node child = srcCloneContentRoot.getFirstChild(); while (child != null) { Node cloneElement = cloneForeignElement(child, contentDom, true); contentRoot.appendChild(cloneElement); child = child.getNextSibling(); } adjustNotePageNumber(slideNum - 1); // in case that the appended new slide have the same name with the original slide hasCheckSlideName = false; checkAllSlideName(); } /** * Make a copy of slide which locates at the specified position of the source presentation * document and insert it to the current presentation document at the new position. The original * slide which at the dest index and after the dest index will move after. * * @param destIndex the new position of the copied slide in the current document * @param srcDoc the source document of the copied slide * @param srcIndex the slide index of the source document that need to be copied * @return the new slide which has the same content with the source slide *

Throw IndexOutOfBoundsException if the slide index is out of the presentation document * slide count If insert the foreign slide at the end of document, destIndex should set the * same value with the slide count of the current presentation document. */ public OdfSlide copyForeignSlide(int destIndex, OdfPresentationDocument srcDoc, int srcIndex) { checkAllSlideName(); OfficePresentationElement contentRoot = null; OdfFileDom contentDom = null; try { contentRoot = getContentRoot(); contentDom = getContentDom(); } catch (Exception e) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, e); return null; } NodeList slideList = contentRoot.getElementsByTagNameNS(OdfDocumentNamespace.DRAW.getUri(), "page"); int slideCount = slideList.getLength(); if ((destIndex < 0) || (destIndex > slideCount)) { throw new IndexOutOfBoundsException( "the specified Index is out of slide count when call copyForeignSlide method."); } OdfSlide sourceSlide = srcDoc.getSlideByIndex(srcIndex); DrawPageElement sourceSlideElement = sourceSlide.getOdfElement(); // clone the sourceSlideEle, and make a modification on this clone node. DrawPageElement sourceCloneSlideElement = (DrawPageElement) sourceSlideElement.cloneNode(true); // copy all the referred xlink:href here copyForeignLinkRef(sourceCloneSlideElement); // copy all the referred style definition here copyForeignStyleRef(sourceCloneSlideElement, srcDoc); // clone the sourceCloneSlideEle, and this cloned element should in the current dom tree DrawPageElement cloneSlideElement = (DrawPageElement) cloneForeignElement(sourceCloneSlideElement, contentDom, true); if (destIndex == slideCount) { contentRoot.appendChild(cloneSlideElement); } else { DrawPageElement refSlide = (DrawPageElement) slideList.item(destIndex); contentRoot.insertBefore(cloneSlideElement, refSlide); } adjustNotePageNumber(destIndex); // in case that the appended new slide have the same name with the original slide hasCheckSlideName = false; checkAllSlideName(); return OdfSlide.getInstance(cloneSlideElement); } // clone the source clone element's referred object path to the current package // if the current package contains the same name with the referred object path, // rename the object path and path reference of this slide element // notes: the source clone element is the copied one to avoid changing the content of the source // document. private void copyForeignLinkRef(OdfElement sourceCloneEle) { try { OdfFileDom fileDom = (OdfFileDom) sourceCloneEle.getOwnerDocument(); XPath xpath; if (fileDom instanceof OdfContentDom) { xpath = ((OdfContentDom) fileDom).getXPath(); } else { xpath = ((OdfStylesDom) fileDom).getXPath(); } OdfPackageDocument srcDoc = fileDom.getDocument(); // new a map to put the original name and the rename string, in case that the same name might // be referred by the slide several times. HashMap objectRenameMap = new HashMap(); NodeList linkNodes = (NodeList) xpath.evaluate(".//*[@xlink:href]", sourceCloneEle, XPathConstants.NODESET); for (int i = 0; i <= linkNodes.getLength(); i++) { OdfElement object = null; if (linkNodes.getLength() == i) { if (sourceCloneEle.hasAttributeNS(OdfDocumentNamespace.XLINK.getUri(), "href")) { object = sourceCloneEle; } else { break; } } else { object = (OdfElement) linkNodes.item(i); } String refObjPath = object.getAttributeNS(OdfDocumentNamespace.XLINK.getUri(), "href"); if (refObjPath != null && refObjPath.length() > 0) { // the path of the object is start with "./" boolean hasPrefix = false; String prefix = "./"; if (refObjPath.startsWith(prefix)) { refObjPath = refObjPath.substring(2); hasPrefix = true; } // check if the current document contains the same path OdfFileEntry fileEntry = getPackage().getFileEntry(refObjPath); // note: if refObjPath is a directory, it must end with '/' if (fileEntry == null) { fileEntry = getPackage().getFileEntry(refObjPath + "/"); } String newObjPath = refObjPath; if (fileEntry != null) { // rename the object path newObjPath = objectRenameMap.get(refObjPath); if (newObjPath == null) { // if refObjPath still contains ".", it means that it has the suffix // then change the name before the suffix string int dotIndex = refObjPath.indexOf("."); if (dotIndex != -1) { newObjPath = refObjPath.substring(0, dotIndex) + "-" + makeUniqueName() + refObjPath.substring(dotIndex); } else { newObjPath = refObjPath + "-" + makeUniqueName(); } objectRenameMap.put(refObjPath, newObjPath); } object.setAttributeNS( OdfDocumentNamespace.XLINK.getUri(), "xlink:href", hasPrefix ? (prefix + newObjPath) : newObjPath); } InputStream is = srcDoc.getPackage().getInputStream(refObjPath); if (is != null) { String mediaType = srcDoc.getPackage().getFileEntry(refObjPath).getMediaTypeString(); getPackage().insert(is, newObjPath, mediaType); } else { OdfDocument embedDoc = (OdfDocument) srcDoc.loadSubDocument(refObjPath); if (embedDoc != null) { insertDocument(embedDoc, newObjPath); } } } } } catch (Exception e) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, e); } } private void copyForeignStyleRef(OdfElement sourceCloneEle, OdfPresentationDocument doc) { try { OdfContentDom contentDom = getContentDom(); XPath xpath = contentDom.getXPath(); // 1. collect all the referred style element which has "style:name" attribute // 1.1. style:name of content.xml String styleQName = "style:name"; NodeList srcStyleDefNodeList = (NodeList) xpath.evaluate("//*[@" + styleQName + "]", contentDom, XPathConstants.NODESET); HashMap> srcContentStyleCloneEleList = new HashMap>(); HashMap appendContentStyleList = new HashMap(); getCopyStyleList( null, sourceCloneEle, styleQName, srcStyleDefNodeList, srcContentStyleCloneEleList, appendContentStyleList, true); // 1.2. style:name of styles.xml srcStyleDefNodeList = (NodeList) xpath.evaluate( "//*[@" + styleQName + "]", doc.getStylesDom(), XPathConstants.NODESET); HashMap> srcStylesStyleCloneEleList = new HashMap>(); HashMap appendStylesStyleList = new HashMap(); getCopyStyleList( null, sourceCloneEle, styleQName, srcStyleDefNodeList, srcStylesStyleCloneEleList, appendStylesStyleList, true); // 1.3 rename, copy the referred style element to the corresponding position in the dom tree insertCollectedStyle( styleQName, srcContentStyleCloneEleList, getContentDom(), appendContentStyleList); insertCollectedStyle( styleQName, srcStylesStyleCloneEleList, getStylesDom(), appendStylesStyleList); // 2. collect all the referred style element which has "draw:name" attribute // 2.1 draw:name of styles.xml // the value of draw:name is string or StyleName, // only when the value is StyleName type, the style definition should be cloned to the // destination document // in ODF spec, such attribute type is only exist in element, so only search // it in styles.xml dom styleQName = "draw:name"; srcStyleDefNodeList = (NodeList) xpath.evaluate( "//*[@" + styleQName + "]", doc.getStylesDom(), XPathConstants.NODESET); HashMap> srcDrawStyleCloneEleList = new HashMap>(); HashMap appendDrawStyleList = new HashMap(); Iterator iter = appendContentStyleList.keySet().iterator(); while (iter.hasNext()) { OdfElement styleElement = iter.next(); OdfElement cloneStyleElement = appendContentStyleList.get(styleElement); getCopyStyleList( styleElement, cloneStyleElement, styleQName, srcStyleDefNodeList, srcDrawStyleCloneEleList, appendDrawStyleList, false); } iter = appendStylesStyleList.keySet().iterator(); while (iter.hasNext()) { OdfElement styleElement = iter.next(); OdfElement cloneStyleElement = appendStylesStyleList.get(styleElement); getCopyStyleList( styleElement, cloneStyleElement, styleQName, srcStyleDefNodeList, srcDrawStyleCloneEleList, appendDrawStyleList, false); } // 2.2 rename, copy the referred style element to the corresponding position in the dom tree // note: "draw:name" style element only exist in styles.dom insertCollectedStyle( styleQName, srcDrawStyleCloneEleList, getStylesDom(), appendDrawStyleList); } catch (Exception e) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, e); } } // 1. modified the style name of the style definition element which has the same name with the // source document // 2. As to the style definition which match 1) condition, modified the referred style name of the // element which reference this style // 3. All the style which also contains other style reference, should be copied to the source // document. private void insertCollectedStyle( String styleQName, HashMap> srcStyleCloneEleList, OdfFileDom dom, HashMap appendStyleList) { try { String stylePrefix = OdfNamespace.getPrefixPart(styleQName); String styleLocalName = OdfNamespace.getLocalPart(styleQName); String styleURI = OdfDocumentNamespace.STYLE.getUri(); // is the DOM always the styles.xml XPath xpath = dom.getXPath(); NodeList destStyleNodeList = (NodeList) xpath.evaluate("//*[@" + styleQName + "]", dom, XPathConstants.NODESET); // HashMap styleRenameMap = new HashMap(); Iterator iter = srcStyleCloneEleList.keySet().iterator(); while (iter.hasNext()) { OdfElement styleElement = iter.next(); OdfElement cloneStyleElement = appendStyleList.get(styleElement); if (cloneStyleElement == null) { cloneStyleElement = (OdfElement) styleElement.cloneNode(true); appendStyleList.put(styleElement, cloneStyleElement); } String styleName = styleElement.getAttributeNS(styleURI, styleLocalName); List newStyleNameList = styleRenameMap.get(styleName); // if the newStyleNameList != null, means that styleName exists in dest document // and it has already been renamed if ((newStyleNameList != null) || (isStyleNameExist(destStyleNodeList, styleName) != null)) { String newStyleName = null; if (newStyleNameList == null) { newStyleNameList = new ArrayList(); newStyleName = styleName + "-" + makeUniqueName(); newStyleNameList.add(newStyleName); styleRenameMap.put(styleName, newStyleNameList); } else { for (int i = 0; i < newStyleNameList.size(); i++) { String styleNameIter = newStyleNameList.get(i); OdfElement destStyleElementWithNewName = isStyleNameExist(destStyleNodeList, styleNameIter); // check if the two style elements have the same content // if not, the cloneStyleElement should rename, rather than reuse the new style name cloneStyleElement.setAttributeNS(styleURI, styleQName, styleNameIter); if ((destStyleElementWithNewName != null) && destStyleElementWithNewName.equals(cloneStyleElement)) { newStyleName = styleNameIter; break; } } if (newStyleName == null) { newStyleName = styleName + "-" + makeUniqueName(); newStyleNameList.add(newStyleName); } } // if newStyleName has been set in the element as the new name // which means that the newStyleName is conform to the odf spec // then change element style reference name if (changeStyleRefName(srcStyleCloneEleList.get(styleElement), styleName, newStyleName)) { cloneStyleElement.setAttributeNS(styleURI, styleQName, newStyleName); // if display name should also be renamed String displayName = cloneStyleElement.getAttributeNS(styleURI, "display-name"); if ((displayName != null) && (displayName.length() > 0)) { cloneStyleElement.setAttributeNS( styleURI, stylePrefix + ":display-name", displayName + newStyleName.substring(newStyleName.length() - 8)); } } } } iter = appendStyleList.keySet().iterator(); while (iter.hasNext()) { OdfElement styleElement = iter.next(); OdfElement cloneStyleElement = appendStyleList.get(styleElement); String newStyleName = cloneStyleElement.getAttributeNS(styleURI, styleLocalName); Boolean isAppended = styleAppendMap.get(newStyleName); // if styleAppendMap contain the newStyleName, // means that cloneStyleElement has already been appended if ((isAppended != null) && isAppended.booleanValue() == true) { continue; } else { styleAppendMap.put(newStyleName, true); } OdfElement cloneForeignStyleElement = (OdfElement) cloneForeignElement(cloneStyleElement, dom, true); String styleElePath = getElementPath(styleElement); appendForeignStyleElement(cloneForeignStyleElement, dom, styleElePath); copyForeignLinkRef(cloneStyleElement); } } catch (Exception e) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, e); } } // get all the copy of referred style element which is directly referred or indirectly referred by // cloneEle // all the style are defined in srcStyleNodeList // and these style are all have the styleName defined in styleQName attribute // the key of copyStyleEleList is the style definition element // the value of the corresponding key is the clone of the element which refer to the key, // the cloned element can be the content of slide or the style element. // the key of appendStyleList is the style definition element which has the other style reference // the value of the corresponding key is the the style definition clone element // loop means if recursive call this function // if loop == true, get the style definition element reference other style definition element private void getCopyStyleList( OdfElement ele, OdfElement cloneEle, String styleQName, NodeList srcStyleNodeList, HashMap> copyStyleEleList, HashMap appendStyleList, boolean loop) { try { String styleLocalName = OdfNamespace.getLocalPart(styleQName); String styleURI = OdfDocumentNamespace.STYLE.getUri(); // OdfElement override the "toString" method String cloneEleStr = cloneEle.toString(); for (int i = 0; i < srcStyleNodeList.getLength(); i++) { OdfElement styleElement = (OdfElement) srcStyleNodeList.item(i); String styleName = styleElement.getAttributeNS(styleURI, styleLocalName); if (styleName != null) { int index = 0; index = cloneEleStr.indexOf("=\"" + styleName + "\"", index); while (index >= 0) { String subStr = cloneEleStr.substring(0, index); int lastSpaceIndex = subStr.lastIndexOf(' '); String attrStr = subStr.substring(lastSpaceIndex + 1, index); XPath xpath = ((OdfFileDom) cloneEle.getOwnerDocument()).getXPath(); NodeList styleRefNodes = (NodeList) xpath.evaluate( ".//*[@" + attrStr + "='" + styleName + "']", cloneEle, XPathConstants.NODESET); boolean isExist = false; for (int j = 0; j <= styleRefNodes.getLength(); j++) { OdfElement styleRefElement = null; if (j == styleRefNodes.getLength()) { isExist = isStyleNameRefExist(cloneEle, styleName, false); if (isExist) { styleRefElement = cloneEle; } else { continue; } } else { OdfElement tmpElement = (OdfElement) styleRefNodes.item(j); if (isStyleNameRefExist(tmpElement, styleName, false)) { styleRefElement = tmpElement; } else { continue; } } boolean hasLoopStyleDef = true; if (copyStyleEleList.get(styleElement) == null) { List styleRefEleList = new ArrayList(); copyStyleEleList.put(styleElement, styleRefEleList); hasLoopStyleDef = false; } copyStyleEleList.get(styleElement).add(styleRefElement); OdfElement cloneStyleElement = appendStyleList.get(styleElement); if (cloneStyleElement == null) { cloneStyleElement = (OdfElement) styleElement.cloneNode(true); appendStyleList.put(styleElement, cloneStyleElement); } if (loop && !hasLoopStyleDef) { getCopyStyleList( styleElement, cloneStyleElement, styleQName, srcStyleNodeList, copyStyleEleList, appendStyleList, loop); } } index = cloneEleStr.indexOf("=\"" + styleName + "\"", index + styleName.length()); } } } } catch (Exception e) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, e); } } // append the cloneStyleElement to the contentDom which position is defined by styleElePath private void appendForeignStyleElement( OdfElement cloneStyleEle, OdfFileDom dom, String styleElePath) { StringTokenizer token = new StringTokenizer(styleElePath, "/"); boolean isExist = true; Node iterNode = dom.getFirstChild(); Node parentNode = dom; while (token.hasMoreTokens()) { String onePath = token.nextToken(); while ((iterNode != null) && isExist) { String path = iterNode.getNamespaceURI(); String prefix = iterNode.getPrefix(); if (prefix == null) { path += "@" + iterNode.getLocalName(); } else { path += "@" + prefix + ":" + iterNode.getLocalName(); } if (!path.equals(onePath)) { // not found, then get the next sibling to find such path node iterNode = iterNode.getNextSibling(); } else { // found, then get the child nodes to find the next path node parentNode = iterNode; iterNode = iterNode.getFirstChild(); break; } } if (iterNode == null) { // should new the element since the current path node if (isExist) { isExist = false; } StringTokenizer token2 = new StringTokenizer(onePath, "@"); OdfElement newElement = dom.createElementNS(OdfName.newName(token2.nextToken(), token2.nextToken())); parentNode.appendChild(newElement); parentNode = newElement; } } parentNode.appendChild(cloneStyleEle); } // The returned string is a path from the top of the dom tree to the specified element // and the path is split by "/" between each node private String getElementPath(OdfElement styleEle) { String path = ""; Node parentNode = styleEle.getParentNode(); while (!(parentNode instanceof OdfFileDom)) { String qname = null; String prefix = parentNode.getPrefix(); if (prefix == null) { qname = parentNode.getLocalName(); } else { qname = prefix + ":" + parentNode.getLocalName(); } path = parentNode.getNamespaceURI() + "@" + qname + "/" + path; parentNode = parentNode.getParentNode(); } return path; } // change the element referred oldStyleName to the new name // if true then set newStyleName attribute value successfully // if false means that the newStyleName value is not conform to the ODF spec, so do not modify the // oldStyleName private boolean changeStyleRefName( List list, String oldStyleName, String newStyleName) { boolean rtn = false; for (int index = 0; index < list.size(); index++) { OdfElement element = list.get(index); NamedNodeMap attributes = element.getAttributes(); if (attributes != null) { for (int i = 0; i < attributes.getLength(); i++) { Node item = attributes.item(i); String value = item.getNodeValue(); if (oldStyleName.equals(value)) { try { item.setNodeValue(newStyleName); rtn = true; break; } catch (IllegalArgumentException e) { return false; } } } } } return rtn; } // check if the element contains the referred styleName private boolean isStyleNameRefExist(Node element, String styleName, boolean deep) { NamedNodeMap attributes = element.getAttributes(); if (attributes != null) { for (int i = 0; i < attributes.getLength(); i++) { Node item = attributes.item(i); if (item.getNodeValue().equals(styleName) && !item.getNodeName().equals("style:name")) // this is style definition, not reference { return true; } } } if (deep) { Node childNode = element.getFirstChild(); while (childNode != null) { if (!isStyleNameRefExist(childNode, styleName, true)) { childNode = childNode.getNextSibling(); } else { return true; } } } return false; } // check if nodeList contains the node that "style:name" attribute has the same value with // styleName // Note: nodeList here is all the style definition list private OdfElement isStyleNameExist(NodeList nodeList, String styleName) { for (int i = 0; i < nodeList.getLength(); i++) { OdfElement element = (OdfElement) nodeList.item(i); String name = element.getAttributeNS(OdfDocumentNamespace.STYLE.getUri(), "name"); if (name.equals(styleName)) // return true; { return element; } } // return false; return null; } private String makeUniqueName() { return String.format("a%06x", (int) (Math.random() * 0xffffff)); } /** * Make a content copy of the specified element, and the returned element should have the * specified ownerDocument. * * @param element The element that need to be copied * @param dom The specified DOM tree that the returned element belong to * @param deep If true, recursively clone the subtree under the element, false, only clone the * element itself * @return Returns a duplicated element which is not in the DOM tree with the specified element */ public Node cloneForeignElement(Node element, OdfFileDom dom, boolean deep) { checkAllSlideName(); if (element instanceof OdfElement) { OdfElement cloneElement = dom.createElementNS(((OdfElement) element).getOdfName()); NamedNodeMap attributes = element.getAttributes(); if (attributes != null) { for (int i = 0; i < attributes.getLength(); i++) { Node item = attributes.item(i); String qname = null; String prefix = item.getPrefix(); if (prefix == null) { qname = item.getLocalName(); } else { qname = prefix + ":" + item.getLocalName(); } cloneElement.setAttributeNS(item.getNamespaceURI(), qname, item.getNodeValue()); } } if (deep) { Node childNode = element.getFirstChild(); while (childNode != null) { cloneElement.appendChild(cloneForeignElement(childNode, dom, true)); childNode = childNode.getNextSibling(); } } return cloneElement; } else { return dom.createTextNode(element.getNodeValue()); } } /** * New a slide at the specified position with the specified name, and use the specified slide * template. See OdfDrawPage.SlideLayout. * *

If index is invalid, such as larger than the current document slide number or is negative, * then append the new slide at the end of the document. * *

The slide name can be null. * * @param index the new slide position * @param name the new slide name * @param slideLayout the new slide template * @return the new slide which locate at the specified position with the specified name and apply * the specified slide template. If slideLayout is null, then use the default slide template * which is a blank slide. *

Throw IndexOutOfBoundsException if index is out of the presentation document slide * count. */ public OdfSlide newSlide(int index, String name, OdfSlide.SlideLayout slideLayout) { checkAllSlideName(); OfficePresentationElement contentRoot = null; try { contentRoot = getContentRoot(); } catch (Exception e) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, e); return null; } NodeList slideList = contentRoot.getElementsByTagNameNS(OdfDocumentNamespace.DRAW.getUri(), "page"); int slideCount = slideList.getLength(); if ((index < 0) || (index > slideCount)) { throw new IndexOutOfBoundsException( "the specified Index is out of slide count when call newSlide method."); } // if insert page at the beginning of the document, // get the next page style as the new page style // else get the previous page style as the new page style DrawPageElement refStyleSlide = null; int refSlideIndex = 0; if (index > 0) { refSlideIndex = index - 1; } refStyleSlide = (DrawPageElement) slideList.item(refSlideIndex); String masterPageStyleName = "Default"; String masterName = refStyleSlide.getDrawMasterPageNameAttribute(); if (masterName != null) { masterPageStyleName = masterName; } DrawPageElement newSlideElement = contentRoot.newDrawPageElement(masterPageStyleName); newSlideElement.setDrawNameAttribute(name); String drawStyleName = refStyleSlide.getDrawStyleNameAttribute(); if (drawStyleName != null) { newSlideElement.setDrawStyleNameAttribute(drawStyleName); } String pageLayoutName = refStyleSlide.getPresentationPresentationPageLayoutNameAttribute(); if (pageLayoutName != null) { newSlideElement.setPresentationPresentationPageLayoutNameAttribute(pageLayoutName); } setSlideLayout(newSlideElement, slideLayout); // insert notes page NodeList noteNodes = refStyleSlide.getElementsByTagNameNS(OdfDocumentNamespace.PRESENTATION.getUri(), "notes"); if (noteNodes.getLength() > 0) { PresentationNotesElement notePage = (PresentationNotesElement) noteNodes.item(0); PresentationNotesElement cloneNotePage = (PresentationNotesElement) notePage.cloneNode(true); newSlideElement.appendChild(cloneNotePage); } if (index < slideCount) { DrawPageElement refSlide = (DrawPageElement) slideList.item(index); contentRoot.insertBefore(newSlideElement, refSlide); } adjustNotePageNumber(index); // in case that the appended new slide have the same name with the original slide hasCheckSlideName = false; checkAllSlideName(); return OdfSlide.getInstance(newSlideElement); } // when insert a slide, the note page for this slide is also inserted. // note page refer the slide index in order to show the corresponding slide notes view // this function is used to adjust note page referred slide index since startIndex // when the slide at startIndex has been delete or insert private void adjustNotePageNumber(int startIndex) { try { OfficePresentationElement contentRoot = getContentRoot(); NodeList slideList = contentRoot.getElementsByTagNameNS(OdfDocumentNamespace.DRAW.getUri(), "page"); for (int i = startIndex; i < getSlideCount(); i++) { DrawPageElement page = (DrawPageElement) slideList.item(i); NodeList noteNodes = page.getElementsByTagNameNS(OdfDocumentNamespace.PRESENTATION.getUri(), "notes"); if (noteNodes.getLength() > 0) { PresentationNotesElement notePage = (PresentationNotesElement) noteNodes.item(0); NodeList thumbnailList = notePage.getElementsByTagNameNS(OdfDocumentNamespace.DRAW.getUri(), "page-thumbnail"); if (thumbnailList.getLength() > 0) { DrawPageThumbnailElement thumbnail = (DrawPageThumbnailElement) thumbnailList.item(0); thumbnail.setDrawPageNumberAttribute(i + 1); } } } } catch (Exception e) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, e); } } // covered element // , , // private void setSlideLayout(DrawPageElement page, OdfSlide.SlideLayout slideLayout) { if (slideLayout == null) { slideLayout = OdfSlide.SlideLayout.BLANK; } OdfOfficeStyles styles = null; try { styles = this.getStylesDom().getOrCreateOfficeStyles(); } catch (SAXException ex) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, ex); } catch (IOException ex) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, ex); } String layoutName; if (slideLayout.toString().equals(OdfSlide.SlideLayout.TITLE_ONLY.toString())) { layoutName = "AL1T" + makeUniqueName(); try { StylePresentationPageLayoutElement layout = styles.newStylePresentationPageLayoutElement(layoutName); layout.newPresentationPlaceholderElement( "title", "2.058cm", "1.743cm", "23.91cm", "3.507cm"); } catch (Exception e1) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, e1); } page.setPresentationPresentationPageLayoutNameAttribute(layoutName); DrawFrameElement frame1 = page.newDrawFrameElement(); frame1.setProperty(StyleGraphicPropertiesElement.StyleShadow, "true"); frame1.setProperty(StyleGraphicPropertiesElement.AutoGrowHeight, "true"); frame1.setProperty(StyleGraphicPropertiesElement.MinHeight, "3.507"); frame1.setPresentationStyleNameAttribute(frame1.getStyleName()); frame1.setDrawLayerAttribute("layout"); frame1.setSvgHeightAttribute("3.006cm"); frame1.setSvgWidthAttribute("24.299cm"); frame1.setSvgXAttribute("1.35cm"); frame1.setSvgYAttribute("0.717cm"); frame1.setPresentationClassAttribute(PresentationClassAttribute.Value.TITLE.toString()); frame1.setPresentationPlaceholderAttribute(true); frame1.newDrawTextBoxElement(); } else if (slideLayout.toString().equals(OdfSlide.SlideLayout.TITLE_OUTLINE.toString())) { layoutName = makeUniqueName(); try { styles = super.getStylesDom().getOfficeStyles(); if (styles == null) { styles = super.getStylesDom().newOdfElement(OdfOfficeStyles.class); } StylePresentationPageLayoutElement layout = styles.newStylePresentationPageLayoutElement(layoutName); layout.newPresentationPlaceholderElement( "title", "2.058cm", "1.743cm", "23.91cm", "3.507cm"); layout.newPresentationPlaceholderElement( "outline", "2.058cm", "1.743cm", "23.91cm", "3.507cm"); } catch (Exception e1) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, e1); } page.setPresentationPresentationPageLayoutNameAttribute(layoutName); DrawFrameElement frame1 = page.newDrawFrameElement(); frame1.setProperty(StyleGraphicPropertiesElement.StyleShadow, "true"); frame1.setProperty(StyleGraphicPropertiesElement.AutoGrowHeight, "true"); frame1.setProperty(StyleGraphicPropertiesElement.MinHeight, "3.507"); frame1.setPresentationStyleNameAttribute(frame1.getStyleName()); frame1.setDrawLayerAttribute("layout"); frame1.setSvgHeightAttribute("3.006cm"); frame1.setSvgWidthAttribute("24.299cm"); frame1.setSvgXAttribute("1.35cm"); frame1.setSvgYAttribute("0.717cm"); frame1.setPresentationClassAttribute(PresentationClassAttribute.Value.TITLE.toString()); frame1.setPresentationPlaceholderAttribute(true); frame1.newDrawTextBoxElement(); DrawFrameElement frame2 = page.newDrawFrameElement(); frame2.setProperty(StyleGraphicPropertiesElement.FillColor, "#ffffff"); frame2.setProperty(StyleGraphicPropertiesElement.MinHeight, "13.114"); frame2.setPresentationStyleNameAttribute(frame2.getStyleName()); frame2.setDrawLayerAttribute("layout"); frame2.setSvgHeightAttribute("11.629cm"); frame2.setSvgWidthAttribute("24.199cm"); frame2.setSvgXAttribute("1.35cm"); frame2.setSvgYAttribute("4.337cm"); frame2.setPresentationClassAttribute(PresentationClassAttribute.Value.OUTLINE.toString()); frame2.setPresentationPlaceholderAttribute(true); frame2.newDrawTextBoxElement(); } else if (slideLayout.toString().equals(OdfSlide.SlideLayout.TITLE_PLUS_TEXT.toString())) { layoutName = makeUniqueName(); try { styles = super.getStylesDom().getOfficeStyles(); if (styles == null) { styles = super.getStylesDom().newOdfElement(OdfOfficeStyles.class); } StylePresentationPageLayoutElement layout = styles.newStylePresentationPageLayoutElement(layoutName); layout.newPresentationPlaceholderElement( "title", "2.058cm", "1.743cm", "23.91cm", "1.743cm"); layout.newPresentationPlaceholderElement( "subtitle", "2.058cm", "5.838cm", "23.91cm", "13.23cm"); } catch (Exception e1) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, e1); } page.setPresentationPresentationPageLayoutNameAttribute(layoutName); DrawFrameElement frame1 = page.newDrawFrameElement(); frame1.setProperty(StyleGraphicPropertiesElement.AutoGrowHeight, "true"); frame1.setProperty(StyleGraphicPropertiesElement.MinHeight, "3.507"); frame1.setPresentationStyleNameAttribute(frame1.getStyleName()); frame1.setDrawLayerAttribute("layout"); frame1.setSvgHeightAttribute("3.006cm"); frame1.setSvgWidthAttribute("24.299cm"); frame1.setSvgXAttribute("1.35cm"); frame1.setSvgYAttribute("0.717cm"); frame1.setPresentationClassAttribute(PresentationClassAttribute.Value.TITLE.toString()); frame1.setPresentationPlaceholderAttribute(true); frame1.newDrawTextBoxElement(); DrawFrameElement frame2 = page.newDrawFrameElement(); frame2.setProperty(StyleGraphicPropertiesElement.AutoGrowHeight, "true"); frame2.setProperty(StyleGraphicPropertiesElement.MinHeight, "3.507"); frame2.setPresentationStyleNameAttribute(frame2.getStyleName()); frame2.setDrawLayerAttribute("layout"); frame2.setSvgHeightAttribute("11.88cm"); frame2.setSvgWidthAttribute("24.299cm"); frame2.setSvgXAttribute("1.35cm"); frame2.setSvgYAttribute("4.712cm"); frame2.setPresentationClassAttribute(PresentationClassAttribute.Value.SUBTITLE.toString()); frame2.setPresentationPlaceholderAttribute(true); frame2.newDrawTextBoxElement(); } else if (slideLayout .toString() .equals(OdfSlide.SlideLayout.TITLE_PLUS_2_TEXT_BLOCK.toString())) { layoutName = makeUniqueName(); try { styles = super.getStylesDom().getOfficeStyles(); if (styles == null) { styles = super.getStylesDom().newOdfElement(OdfOfficeStyles.class); } StylePresentationPageLayoutElement layout = styles.newStylePresentationPageLayoutElement(layoutName); layout.newPresentationPlaceholderElement( "outline", "2.058cm", "1.743cm", "23.91cm", "1.743cm"); layout.newPresentationPlaceholderElement( "outline", "1.35cm", "4.212cm", "11.857cm", "11.629cm"); layout.newPresentationPlaceholderElement( "outline", "4.212cm", "13.8cm", "11.857cm", "11.629cm"); } catch (Exception e1) { Logger.getLogger(OdfPresentationDocument.class.getName()).log(Level.SEVERE, null, e1); } DrawFrameElement frame1 = page.newDrawFrameElement(); frame1.setProperty(StyleGraphicPropertiesElement.AutoGrowHeight, "true"); frame1.setProperty(StyleGraphicPropertiesElement.MinHeight, "3.507"); frame1.setPresentationStyleNameAttribute(frame1.getStyleName()); frame1.setDrawLayerAttribute("layout"); frame1.setSvgHeightAttribute("3.006cm"); frame1.setSvgWidthAttribute("24.299cm"); frame1.setSvgXAttribute("1.35cm"); frame1.setSvgYAttribute("0.717cm"); frame1.setPresentationClassAttribute(PresentationClassAttribute.Value.TITLE.toString()); frame1.setPresentationPlaceholderAttribute(true); frame1.newDrawTextBoxElement(); DrawFrameElement frame2 = page.newDrawFrameElement(); frame2.setProperty(StyleGraphicPropertiesElement.AutoGrowHeight, "true"); frame2.setProperty(StyleGraphicPropertiesElement.MinHeight, "3.507"); frame2.setPresentationStyleNameAttribute(frame2.getStyleName()); frame2.setDrawLayerAttribute("layout"); frame2.setSvgHeightAttribute("11.629cm"); frame2.setSvgWidthAttribute("11.857cm"); frame2.setSvgXAttribute("1.35cm"); frame2.setSvgYAttribute("4.212cm"); frame2.setPresentationClassAttribute(PresentationClassAttribute.Value.OUTLINE.toString()); frame2.setPresentationPlaceholderAttribute(true); frame2.newDrawTextBoxElement(); DrawFrameElement frame3 = page.newDrawFrameElement(); frame3.setProperty(StyleGraphicPropertiesElement.AutoGrowHeight, "true"); frame3.setProperty(StyleGraphicPropertiesElement.MinHeight, "3.507"); frame3.setPresentationStyleNameAttribute(frame3.getStyleName()); frame3.setDrawLayerAttribute("layout"); frame3.setSvgHeightAttribute("11.62cm"); frame3.setSvgWidthAttribute("11.857cm"); frame3.setSvgXAttribute("13.8cm"); frame3.setSvgYAttribute("4.212cm"); frame3.setPresentationClassAttribute(PresentationClassAttribute.Value.OUTLINE.toString()); frame3.setPresentationPlaceholderAttribute(true); frame3.newDrawTextBoxElement(); page.setPresentationPresentationPageLayoutNameAttribute(layoutName); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy