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

org.odftoolkit.simple.TextDocument Maven / Gradle / Ivy

There is a newer version: 0.8.2-incubating
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.simple;

import java.awt.Rectangle;
import java.io.File;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.odftoolkit.odfdom.dom.OdfContentDom;
import org.odftoolkit.odfdom.dom.OdfDocumentNamespace;
import org.odftoolkit.odfdom.dom.attribute.text.TextAnchorTypeAttribute;
import org.odftoolkit.odfdom.dom.element.draw.DrawControlElement;
import org.odftoolkit.odfdom.dom.element.draw.DrawFrameElement;
import org.odftoolkit.odfdom.dom.element.office.OfficeDocumentStylesElement;
import org.odftoolkit.odfdom.dom.element.office.OfficeFormsElement;
import org.odftoolkit.odfdom.dom.element.office.OfficeMasterStylesElement;
import org.odftoolkit.odfdom.dom.element.office.OfficeTextElement;
import org.odftoolkit.odfdom.dom.element.style.StyleColumnsElement;
import org.odftoolkit.odfdom.dom.element.style.StyleFooterElement;
import org.odftoolkit.odfdom.dom.element.style.StyleHeaderElement;
import org.odftoolkit.odfdom.dom.element.style.StyleMasterPageElement;
import org.odftoolkit.odfdom.dom.element.style.StylePageLayoutPropertiesElement;
import org.odftoolkit.odfdom.dom.element.style.StyleSectionPropertiesElement;
import org.odftoolkit.odfdom.dom.element.table.TableTableElement;
import org.odftoolkit.odfdom.dom.element.text.TextIndexBodyElement;
import org.odftoolkit.odfdom.dom.element.text.TextIndexEntryLinkStartElement;
import org.odftoolkit.odfdom.dom.element.text.TextIndexEntryTabStopElement;
import org.odftoolkit.odfdom.dom.element.text.TextIndexSourceStylesElement;
import org.odftoolkit.odfdom.dom.element.text.TextIndexTitleElement;
import org.odftoolkit.odfdom.dom.element.text.TextIndexTitleTemplateElement;
import org.odftoolkit.odfdom.dom.element.text.TextPElement;
import org.odftoolkit.odfdom.dom.element.text.TextParagraphElementBase;
import org.odftoolkit.odfdom.dom.element.text.TextSectionElement;
import org.odftoolkit.odfdom.dom.element.text.TextSequenceDeclsElement;
import org.odftoolkit.odfdom.dom.element.text.TextTableOfContentElement;
import org.odftoolkit.odfdom.dom.element.text.TextTableOfContentEntryTemplateElement;
import org.odftoolkit.odfdom.dom.element.text.TextTableOfContentSourceElement;
import org.odftoolkit.odfdom.dom.element.text.TextTocMarkElement;
import org.odftoolkit.odfdom.dom.element.text.TextTocMarkStartElement;
import org.odftoolkit.odfdom.dom.style.OdfStyleFamily;
import org.odftoolkit.odfdom.incubator.doc.office.OdfOfficeAutomaticStyles;
import org.odftoolkit.odfdom.incubator.doc.office.OdfOfficeMasterStyles;
import org.odftoolkit.odfdom.incubator.doc.office.OdfOfficeStyles;
import org.odftoolkit.odfdom.incubator.doc.style.OdfStyle;
import org.odftoolkit.odfdom.incubator.doc.style.OdfStylePageLayout;
import org.odftoolkit.odfdom.incubator.doc.text.OdfTextParagraph;
import org.odftoolkit.odfdom.pkg.MediaType;
import org.odftoolkit.odfdom.pkg.OdfElement;
import org.odftoolkit.odfdom.pkg.OdfFileDom;
import org.odftoolkit.odfdom.pkg.OdfPackage;
import org.odftoolkit.odfdom.type.CellRangeAddressList;
import org.odftoolkit.odfdom.type.Length.Unit;
import org.odftoolkit.simple.chart.AbstractChartContainer;
import org.odftoolkit.simple.chart.Chart;
import org.odftoolkit.simple.chart.ChartContainer;
import org.odftoolkit.simple.chart.DataSet;
import org.odftoolkit.simple.common.field.AbstractVariableContainer;
import org.odftoolkit.simple.common.field.VariableContainer;
import org.odftoolkit.simple.common.field.VariableField;
import org.odftoolkit.simple.common.field.VariableField.VariableType;
import org.odftoolkit.simple.draw.Control;
import org.odftoolkit.simple.draw.ControlContainer;
import org.odftoolkit.simple.form.AbstractFormContainer;
import org.odftoolkit.simple.form.Form;
import org.odftoolkit.simple.form.FormContainer;
import org.odftoolkit.simple.style.MasterPage;
import org.odftoolkit.simple.style.TOCStyle;
import org.odftoolkit.simple.table.Table;
import org.odftoolkit.simple.text.AbstractParagraphContainer;
import org.odftoolkit.simple.text.Footer;
import org.odftoolkit.simple.text.Header;
import org.odftoolkit.simple.text.Paragraph;
import org.odftoolkit.simple.text.ParagraphContainer;
import org.odftoolkit.simple.text.Section;
import org.odftoolkit.simple.text.list.AbstractListContainer;
import org.odftoolkit.simple.text.list.List;
import org.odftoolkit.simple.text.list.ListContainer;
import org.odftoolkit.simple.text.list.ListDecorator;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

/**
 * This class represents an empty ODF text document.
 * 
 */
public class TextDocument extends Document implements ListContainer,
		ParagraphContainer, VariableContainer, ChartContainer, FormContainer,
		ControlContainer {

	private static final String EMPTY_TEXT_DOCUMENT_PATH = "/OdfTextDocument.odt";
	static final Resource EMPTY_TEXT_DOCUMENT_RESOURCE = new Resource(EMPTY_TEXT_DOCUMENT_PATH);

	private ListContainerImpl listContainerImpl;
	private ParagraphContainerImpl paragraphContainerImpl;
	private VariableContainerImpl variableContainerImpl;
	private ChartContainerImpl chartContainerImpl;
	private FormContainerImpl formContainerImpl = null;
	
	private Header firstPageHeader;
	private Header standardHeader;

	private Footer firstPageFooter;
	private Footer standardFooter;

	/**
	 * This enum contains all possible media types of SpreadsheetDocument
	 * documents.
	 */
	public enum OdfMediaType implements MediaType {

		TEXT(Document.OdfMediaType.TEXT), TEXT_TEMPLATE(Document.OdfMediaType.TEXT_TEMPLATE), TEXT_MASTER(
				Document.OdfMediaType.TEXT_MASTER), TEXT_WEB(Document.OdfMediaType.TEXT_WEB);
		private final Document.OdfMediaType mMediaType;

		OdfMediaType(Document.OdfMediaType mediaType) {
			this.mMediaType = mediaType;
		}

		/**
		 * @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 Document.OdfMediaType getOdfMediaType(String mediaType) {
			return Document.OdfMediaType.getOdfMediaType(mediaType);
		}
	}

	/**
	 * Creates an empty text document.
	 * 
	 * @return ODF text document based on a default template
	 * @throws java.lang.Exception
	 *             - if the document could not be created
	 */
	public static TextDocument newTextDocument() throws Exception {
		return (TextDocument) Document.loadTemplate(EMPTY_TEXT_DOCUMENT_RESOURCE, Document.OdfMediaType.TEXT);
	}

	/**
	 * Creates an empty text document.
	 * 
	 * @return ODF text document based on a default template
	 * @throws java.lang.Exception
	 *             - if the document could not be created
	 */
	public static TextDocument newTextDocument(TextDocument.OdfMediaType mimeType) throws Exception {
		return (TextDocument) Document.loadTemplate(EMPTY_TEXT_DOCUMENT_RESOURCE, Document.OdfMediaType.TEXT);
	}

	/**
	 * Creates an empty text template.
	 * 
	 * @return ODF text template based on a default
	 * @throws java.lang.Exception
	 *             - if the template could not be created
	 */
	public static TextDocument newTextTemplateDocument() throws Exception {
		return (TextDocument) Document.loadTemplate(EMPTY_TEXT_DOCUMENT_RESOURCE, Document.OdfMediaType.TEXT_TEMPLATE);
	}

	/**
	 * Creates an empty text master document.
	 * 
	 * @return ODF text master based on a default
	 * @throws java.lang.Exception
	 *             - if the document could not be created
	 */
	public static TextDocument newTextMasterDocument() throws Exception {
		TextDocument doc = (TextDocument) Document.loadTemplate(EMPTY_TEXT_DOCUMENT_RESOURCE,
				Document.OdfMediaType.TEXT_MASTER);
		doc.changeMode(OdfMediaType.TEXT_MASTER);
		return doc;
	}

	/**
	 * Creates an empty text web.
	 * 
	 * @return ODF text web based on a default
	 * @throws java.lang.Exception
	 *             - if the document could not be created
	 */
	public static TextDocument newTextWebDocument() throws Exception {
		TextDocument doc = (TextDocument) Document.loadTemplate(EMPTY_TEXT_DOCUMENT_RESOURCE,
				Document.OdfMediaType.TEXT_WEB);
		doc.changeMode(OdfMediaType.TEXT_WEB);
		return doc;
	}

	/**
	 * Creates an TextDocument from the OpenDocument provided by a resource
	 * Stream.
	 * 
	 * 

* Since an InputStream does not provide the arbitrary (non sequentiell) * read access needed by TextDocument, 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 text document, ClassCastException * might be thrown. *

* * @param inputStream * - the InputStream of the ODF text document. * @return the text document created from the given InputStream * @throws java.lang.Exception * - if the document could not be created. */ public static TextDocument loadDocument(InputStream inputStream) throws Exception { return (TextDocument) Document.loadDocument(inputStream); } /** * Loads an TextDocument from the provided path. * *

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

* *

* If the resource stream is not a ODF text document, ClassCastException * might be thrown. *

* * @param documentPath * - the path from where the document can be loaded * @return the text document from the given path or NULL if the media type * is not supported by SIMPLE. * @throws java.lang.Exception * - if the document could not be created. */ public static TextDocument loadDocument(String documentPath) throws Exception { return (TextDocument) Document.loadDocument(documentPath); } /** * Creates an TextDocument from the OpenDocument provided by a File. * *

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

* *

* If the resource stream is not a ODF text document, ClassCastException * might be thrown. *

* * @param file * - a file representing the ODF text document. * @return the text document created from the given File * @throws java.lang.Exception * - if the document could not be created. */ public static TextDocument loadDocument(File file) throws Exception { return (TextDocument) Document.loadDocument(file); } /** * 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 TextDocument(OdfPackage pkg, String internalPath, TextDocument.OdfMediaType odfMediaType) { super(pkg, internalPath, odfMediaType.mMediaType); } /** * Get the content root of a text document. Start here to get or create new * elements of a text document like paragraphs, headings, tables or lists. * * @return content root, representing the office:text tag * @throws Exception * if the file DOM could not be created. */ @Override public OfficeTextElement getContentRoot() throws Exception { return super.getContentRoot(OfficeTextElement.class); } /** * Creates a new paragraph and append text * * @param text * @return the new paragraph * @throws Exception * if the file DOM could not be created. * @deprecated As of Simple version 0.5, replaced by * addParagraph(String text) * @see #addParagraph(String) */ public OdfTextParagraph newParagraph(String text) throws Exception { OdfTextParagraph para = newParagraph(); para.addContent(text); return para; } /** * Creates a new paragraph * * @return The new paragraph * @throws Exception * if the file DOM could not be created. * @deprecated As of Simple version 0.5, replaced by * Paragraph.newParagraph(ParagraphContainer) * @see Paragraph#newParagraph(ParagraphContainer) * @see #addParagraph(String) */ public OdfTextParagraph newParagraph() throws Exception { OfficeTextElement odfText = getContentRoot(); return (OdfTextParagraph) odfText.newTextPElement(); } /** * Append text to the end of a text document. If there is no paragraph at * the end of a document, a new one will be created. * * @param text * initial text for the paragraph. * @return The paragraph at the end of the text document, where the text has * been added to. * @throws Exception * if the file DOM could not be created. * @deprecated As of Simple version 0.5, replaced by * Paragraph.appendTextContent(String content) * @see Paragraph#appendTextContent(String) * @see Paragraph#appendTextContentNotCollapsed(String) * @see #getParagraphByIndex(int, boolean) * @see #getParagraphByReverseIndex(int, boolean) */ public OdfTextParagraph addText(String text) throws Exception { OfficeTextElement odfText = getContentRoot(); Node n = odfText.getLastChild(); OdfTextParagraph para; if (OdfTextParagraph.class.isInstance(n)) { para = (OdfTextParagraph) n; } else { para = newParagraph(); } para.addContent(text); return para; } /** * Changes the document to the given mediatype. This method can only be used * to convert a document to a related mediatype, e.g. template. * * @param mediaType * the related ODF mimetype */ public void changeMode(OdfMediaType mediaType) { setOdfMediaType(mediaType.mMediaType); } /** * Copy a section and append it at the end of the text document, whether the * section is in this document or in a different document. *

* The IDs and names in this section would be changed to ensure unique. *

* If the section contains a linked resource, isResourceCopied * would specify whether the linked resource would be copied or not, when * the copy and append happens within a same document. * * @param section * - the section object * @param isResourceCopied * - whether the linked resource is copied or not. */ public Section appendSection(Section section, boolean isResourceCopied) { boolean isForeignNode = false; try { if (section.getOdfElement().getOwnerDocument() != getContentDom()) isForeignNode = true; TextSectionElement oldSectionEle = section.getOdfElement(); TextSectionElement newSectionEle = (TextSectionElement) oldSectionEle.cloneNode(true); if (isResourceCopied || isForeignNode) copyLinkedRefInBatch(newSectionEle, section.getOwnerDocument()); if (isForeignNode) copyForeignStyleRef(newSectionEle, section.getOwnerDocument()); if (isForeignNode) // not in a same document newSectionEle = (TextSectionElement) cloneForeignElement(newSectionEle, getContentDom(), true); updateNames(newSectionEle); updateXMLIds(newSectionEle); OfficeTextElement contentRoot = getContentRoot(); contentRoot.appendChild(newSectionEle); return Section.getInstance(newSectionEle); } catch (Exception e) { Logger.getLogger(TextDocument.class.getName()).log(Level.SEVERE, null, e); } return null; } /** * Create an empty section and append it at the end of the text document. * * @param name * - specify the section name * @return an instance of the section * @throws RuntimeException * if content DOM could not be initialized */ public Section appendSection(String name) { TextSectionElement newSectionEle = null; try { OdfContentDom contentDocument = getContentDom(); OdfOfficeAutomaticStyles styles = contentDocument .getAutomaticStyles(); OdfStyle style = styles.newStyle(OdfStyleFamily.Section); StyleSectionPropertiesElement sProperties = style .newStyleSectionPropertiesElement(); sProperties.setTextDontBalanceTextColumnsAttribute(false); sProperties.setStyleEditableAttribute(false); StyleColumnsElement columnEle = sProperties .newStyleColumnsElement(1); columnEle.setFoColumnGapAttribute("0in"); newSectionEle = getContentRoot() .newTextSectionElement("true", name); newSectionEle.setStyleName(style.getStyleNameAttribute()); return Section.getInstance(newSectionEle); } catch (Exception e) { Logger.getLogger(TextDocument.class.getName()).log(Level.SEVERE, null, e); throw new RuntimeException(name + "Section appends failed.", e); } } /** * Get the Standard Page header of this text document. * * @return the Standard Page header of this text document. * @since 0.4.5 */ public Header getHeader() { return getHeader(false); } /** * Get the header of this text document. * * @param isFirstPage * if isFirstPage is true, return the First Page * header, otherwise return Standard Page header. * * @return the header of this text document. * @since 0.5 */ public Header getHeader(boolean isFirstPage) { Header tmpHeader = isFirstPage ? firstPageHeader : standardHeader; if (tmpHeader == null) { try { StyleMasterPageElement masterPageElement = getMasterPage(isFirstPage); StyleHeaderElement headerElement = OdfElement.findFirstChildNode(StyleHeaderElement.class, masterPageElement); if (headerElement == null) { headerElement = masterPageElement.newStyleHeaderElement(); } tmpHeader = new Header(headerElement); } catch (Exception e) { Logger.getLogger(TextDocument.class.getName()).log(Level.SEVERE, null, e); } if (isFirstPage) { firstPageHeader = tmpHeader; } else { standardHeader = tmpHeader; } } return tmpHeader; } /** * Get the Standard Page footer of this text document. * * @return the Standard Page footer of this text document. * @since 0.4.5 */ public Footer getFooter() { return getFooter(false); } /** * Get the footer of this text document. * * @param isFirstPage * if isFirstPage is true, return the First Page * footer, otherwise return Standard Page footer. * * @return the footer of this text document. * @since 0.5 */ public Footer getFooter(boolean isFirstPage) { Footer tmpFooter = isFirstPage ? firstPageFooter : standardFooter; if (tmpFooter == null) { try { StyleMasterPageElement masterPageElement = getMasterPage(isFirstPage); StyleFooterElement footerElement = OdfElement.findFirstChildNode(StyleFooterElement.class, masterPageElement); if (footerElement == null) { footerElement = masterPageElement.newStyleFooterElement(); } tmpFooter = new Footer(footerElement); } catch (Exception e) { Logger.getLogger(TextDocument.class.getName()).log(Level.SEVERE, null, e); } if (isFirstPage) { firstPageFooter = tmpFooter; } else { standardFooter = tmpFooter; } } return tmpFooter; } public OdfElement getTableContainerElement() { return getTableContainerImpl().getTableContainerElement(); } public OdfElement getListContainerElement() { return getListContainerImpl().getListContainerElement(); } public List addList() { return getListContainerImpl().addList(); } public List addList(ListDecorator decorator) { return getListContainerImpl().addList(decorator); } public void clearList() { getListContainerImpl().clearList(); } public Iterator getListIterator() { return getListContainerImpl().getListIterator(); } public boolean removeList(List list) { return getListContainerImpl().removeList(list); } /** * Appends a new page break to this document. * * @since 0.6.5 */ public void addPageBreak() { addPageOrColumnBreak(null, "page"); } /** * Appends a new page break to this document after the reference paragraph. * * @param refParagraph * the reference paragraph after where the page break inserted. * @since 0.6.5 */ public void addPageBreak(Paragraph refParagraph) { addPageOrColumnBreak(refParagraph, "page"); } /** * Defines several columns to the page whose style is specified. * * @param columnsNumber * the number of columns (are of width identical) * @param spacing * column spacing in cm (ex. 2.40 for 2,4 cm) * * @since 0.6.6 */ public void setPageColumns(int columnsNumber, double spacing) { String vSpacingColumn = (new DecimalFormat("#0.###").format(spacing) + Unit.CENTIMETER.abbr()).replace(",", "."); // Get back the name of the style Page wanted Layout // (Example of the got back name : pm1 or Mpm1 for the standard style) try { String stylePageLayoutName = null; int pageLayoutNameCount = 0; NodeList list = getStylesDom().getElementsByTagName("office:master-styles"); if (list.getLength() > 0) { OdfOfficeMasterStyles officeMasterStyles = (OdfOfficeMasterStyles) list.item(0); // Get back the StylePageLayoutName for (int i = 0; i < officeMasterStyles.getLength(); i++) { StyleMasterPageElement syleMasterPage = (StyleMasterPageElement) officeMasterStyles.item(i); if(syleMasterPage.getStyleNameAttribute().equals("Standard")){ stylePageLayoutName = syleMasterPage.getStylePageLayoutNameAttribute(); break; } } // Allows to know if StylePageLayoutName is unique for (int i = 0; i < officeMasterStyles.getLength(); i++) { StyleMasterPageElement syleMasterPage = (StyleMasterPageElement) officeMasterStyles.item(i); if(syleMasterPage.getStylePageLayoutNameAttribute().equals(stylePageLayoutName)){ pageLayoutNameCount++; } } } OdfOfficeAutomaticStyles autoStyles = getStylesDom().getAutomaticStyles(); int autoStylesCount = autoStyles.getLength(); OdfStylePageLayout pageLayout = autoStyles.getPageLayout(stylePageLayoutName); if(pageLayout != null) { // Clone the OdfStylePageLayout if another master style possesses the same name before modifying its properties if(pageLayoutNameCount > 1){ Node pageLayoutNew = pageLayout.cloneNode(true); // Rename the style of the clone before modifying its properties String oldPageLayoutName = pageLayout.getStyleNameAttribute(); pageLayout.setStyleNameAttribute("Mpm" + (autoStylesCount+1)); // Allocate the new name of the style to the master style (the cloned style) if (list.getLength() > 0) { OdfOfficeMasterStyles masterpage = (OdfOfficeMasterStyles) list.item(0); for (int i = 0; i < masterpage.getLength(); i++) { StyleMasterPageElement vSyleMasterPage = (StyleMasterPageElement) masterpage.item(i); if(vSyleMasterPage.getStyleNameAttribute().equals("Standard")){ if(vSyleMasterPage.getStylePageLayoutNameAttribute().equals(oldPageLayoutName)){ vSyleMasterPage.setStylePageLayoutNameAttribute(pageLayout.getStyleNameAttribute()); } } } } autoStyles.appendChild(pageLayoutNew); } NodeList vListStlePageLprop = pageLayout.getElementsByTagName("style:page-layout-properties"); StylePageLayoutPropertiesElement vStlePageLprop = (StylePageLayoutPropertiesElement) vListStlePageLprop.item(0); StyleColumnsElement vStyleColumnsElement = vStlePageLprop.newStyleColumnsElement(columnsNumber); vStyleColumnsElement.setFoColumnGapAttribute(vSpacingColumn); } } catch (Exception e) { Logger.getLogger(TextDocument.class.getName()).log(Level.SEVERE, null, e); throw new RuntimeException("Page column sets failed.", e); } } /** * Appends a new column break to this document. * * @since 0.6.6 */ public void addColumnBreak() { addPageOrColumnBreak(null, "column"); } /** * Appends a new column break to this document after the reference paragraph. * * @param refParagraph * the reference paragraph after where the column break inserted. * @since 0.6.6 */ public void addColumnBreak(Paragraph refParagraph) { addPageOrColumnBreak(refParagraph, "column"); } /** * Appends a new column or page break to this document. * * @param refParagraph * the reference paragraph after where the column break inserted. * @param breakAttribute * the attribute name (page or column) */ private void addPageOrColumnBreak(Paragraph refParagraph, String breakAttribute) { TextPElement pEle = null; try { OdfContentDom contentDocument = getContentDom(); OdfOfficeAutomaticStyles styles = contentDocument.getAutomaticStyles(); OdfStyle style = styles.newStyle(OdfStyleFamily.Paragraph); style.newStyleParagraphPropertiesElement().setFoBreakBeforeAttribute(breakAttribute); if(refParagraph == null){ pEle = getContentRoot().newTextPElement(); } else { OfficeTextElement contentRoot = getContentRoot(); pEle = contentRoot.newTextPElement(); OdfElement refEle = refParagraph.getOdfElement(); contentRoot.insertBefore(pEle, refEle.getNextSibling()); } pEle.setStyleName(style.getStyleNameAttribute()); } catch (Exception e) { Logger.getLogger(TextDocument.class.getName()).log(Level.SEVERE, null, e); throw new RuntimeException(breakAttribute + "Break appends failed.", e); } } /** * Appends a new page break to this document after the reference paragraph, * and the master page style will be applied to the new page. * * @param refParagraph * the reference paragraph after where the page break inserted. * @param master * the master page style applied to the new page. * @since 0.8 */ public void addPageBreak(Paragraph refParagraph, MasterPage master) { TextPElement pEle = null; try { OdfContentDom contentDocument = getContentDom(); OdfOfficeAutomaticStyles styles = contentDocument .getAutomaticStyles(); OdfStyle style = styles.newStyle(OdfStyleFamily.Paragraph); style.setStyleMasterPageNameAttribute(master.getName()); if (refParagraph == null) { pEle = getContentRoot().newTextPElement(); } else { OfficeTextElement contentRoot = getContentRoot(); pEle = contentRoot.newTextPElement(); OdfElement refEle = refParagraph.getOdfElement(); contentRoot.insertBefore(pEle, refEle.getNextSibling()); } pEle.setStyleName(style.getStyleNameAttribute()); } catch (Exception e) { Logger.getLogger(TextDocument.class.getName()).log(Level.SEVERE, null, e); throw new RuntimeException("PageBreak with mater page - " + master.getName() + " - appends failed.", e); } } /** * Creates a new paragraph and append text. * * @param text * the text content of this paragraph * @return the new paragraph */ public Paragraph addParagraph(String text) { Paragraph para = getParagraphContainerImpl().addParagraph(text); return para; } /** * Remove paragraph from this document * * @param para * the instance of paragraph * @return true if the paragraph is removed successfully, false if errors * happen. */ public boolean removeParagraph(Paragraph para) { return getParagraphContainerImpl().removeParagraph(para); } public OdfElement getParagraphContainerElement() { return getParagraphContainerImpl().getParagraphContainerElement(); } public Paragraph getParagraphByIndex(int index, boolean isEmptyParagraphSkipped) { return getParagraphContainerImpl().getParagraphByIndex(index, isEmptyParagraphSkipped); } public Paragraph getParagraphByReverseIndex(int reverseIndex, boolean isEmptyParagraphSkipped) { return getParagraphContainerImpl().getParagraphByReverseIndex(reverseIndex, isEmptyParagraphSkipped); } public Iterator getParagraphIterator() { return getParagraphContainerImpl().getParagraphIterator(); } public VariableField declareVariable(String name, VariableType type) { return getVariableContainerImpl().declareVariable(name, type); } public VariableField getVariableFieldByName(String name) { return getVariableContainerImpl().getVariableFieldByName(name); } public OdfElement getVariableContainerElement() { return getVariableContainerImpl().getVariableContainerElement(); } public Chart createChart(String title, DataSet dataset, Rectangle rect) { return getChartContainerImpl().createChart(title, dataset, rect); } public Chart createChart(String title, SpreadsheetDocument document, CellRangeAddressList cellRangeAddr, boolean firstRowAsLabel, boolean firstColumnAsLabel, boolean rowAsDataSeries, Rectangle rect) { return getChartContainerImpl().createChart(title, document, cellRangeAddr, firstRowAsLabel, firstColumnAsLabel, rowAsDataSeries, rect); } public Chart createChart(String title, String[] labels, String[] legends, double[][] data, Rectangle rect) { return getChartContainerImpl().createChart(title, labels, legends, data, rect); } public void deleteChartById(String chartId) { getChartContainerImpl().deleteChartById(chartId); } public void deleteChartByTitle(String title) { getChartContainerImpl().deleteChartByTitle(title); } public Chart getChartById(String chartId) { return getChartContainerImpl().getChartById(chartId); } public java.util.List getChartByTitle(String title) { return getChartContainerImpl().getChartByTitle(title); } public int getChartCount() { return getChartContainerImpl().getChartCount(); } private ListContainerImpl getListContainerImpl() { if (listContainerImpl == null) { listContainerImpl = new ListContainerImpl(); } return listContainerImpl; } private class ListContainerImpl extends AbstractListContainer { public OdfElement getListContainerElement() { OdfElement containerElement = null; try { containerElement = getContentRoot(); } catch (Exception e) { Logger.getLogger(TextDocument.class.getName()).log(Level.SEVERE, null, e); } return containerElement; } } private StyleMasterPageElement getMasterPage(boolean pFirstPage) throws Exception { String pageStyleName = pFirstPage ? "First_20_Page" : "Standard"; OfficeDocumentStylesElement rootElement = getStylesDom().getRootElement(); OfficeMasterStylesElement masterStyles = OdfElement.findFirstChildNode(OfficeMasterStylesElement.class, rootElement); if (masterStyles == null) { masterStyles = rootElement.newOfficeMasterStylesElement(); } StyleMasterPageElement masterPageEle = null; NodeList lastMasterPages = masterStyles.getElementsByTagNameNS(OdfDocumentNamespace.STYLE.getUri(), "master-page"); if (lastMasterPages != null && lastMasterPages.getLength() > 0) { for (int i = 0; i < lastMasterPages.getLength(); i++) { StyleMasterPageElement masterPage = (StyleMasterPageElement) lastMasterPages.item(i); String styleName = masterPage.getStyleNameAttribute(); if (pageStyleName.equals(styleName)) { masterPageEle = masterPage; break; } } } if (masterPageEle == null) { OdfStylePageLayout layout = OdfElement.findFirstChildNode(OdfStylePageLayout.class, getStylesDom() .getAutomaticStyles()); masterPageEle = masterStyles.newStyleMasterPageElement(pageStyleName, layout.getStyleNameAttribute()); } return masterPageEle; } private class ParagraphContainerImpl extends AbstractParagraphContainer { public OdfElement getParagraphContainerElement() { OdfElement containerElement = null; try { containerElement = getContentRoot(); } catch (Exception e) { Logger.getLogger(TextDocument.class.getName()).log(Level.SEVERE, null, e); } return containerElement; } } private ParagraphContainerImpl getParagraphContainerImpl() { if (paragraphContainerImpl == null) paragraphContainerImpl = new ParagraphContainerImpl(); return paragraphContainerImpl; } private class VariableContainerImpl extends AbstractVariableContainer { public OdfElement getVariableContainerElement() { try { return getContentRoot(); } catch (Exception e) { Logger.getLogger(TextDocument.class.getName()).log(Level.SEVERE, null, e); return null; } } } private VariableContainer getVariableContainerImpl() { if (variableContainerImpl == null) { variableContainerImpl = new VariableContainerImpl(); } return variableContainerImpl; } private ChartContainerImpl getChartContainerImpl() { if (chartContainerImpl == null) { chartContainerImpl = new ChartContainerImpl(this); } return chartContainerImpl; } private class ChartContainerImpl extends AbstractChartContainer { TextDocument sdoc; protected ChartContainerImpl(Document doc) { super(doc); sdoc = (TextDocument) doc; } protected DrawFrameElement getChartFrame() throws Exception { OdfContentDom contentDom2 = sdoc.getContentDom(); DrawFrameElement drawFrame = contentDom2.newOdfElement(DrawFrameElement.class); TextPElement lastPara = sdoc.getContentRoot().newTextPElement(); lastPara.appendChild(drawFrame); drawFrame.setTextAnchorTypeAttribute(TextAnchorTypeAttribute.Value.PARAGRAPH.toString()); return drawFrame; } } /** * Create a new Table Of Content to this document before the reference * paragraph. Because until you do a full layout of the document, taking * into account font metrics,line breaking algorithms, hyphenation, image * positioning, "orphan and widow" rules, etc., you don't know what content * is on which page. So all the page numbers in TOC are be set value "1". * Please update the page numbers from AOO Menus: Tools->Update->All Indexes * and Tables * * @param refParagraph * the reference paragraph where the TOC be inserted. * @param before * true:insert TOC before the reference paragraph. false:insert * TOC after the reference paragraph. * @since 0.8.6 */ public TextTableOfContentElement createDefaultTOC(Paragraph refParagraph, boolean before) { TextTableOfContentElement textTableOfContent =null; if(refParagraph==null){ Logger.getLogger(TextDocument.class.getName()).log(Level.SEVERE, "Failed to create Default TOC, The refParagraph where the TOC be inserted is null"); throw new RuntimeException("Failed to create Default TOC, The refParagraph where the TOC be inserted is null"); } Node refparagraphNode = refParagraph.getOdfElement(); Node rootNode = refparagraphNode.getParentNode(); try { OdfContentDom content = getContentDom(); textTableOfContent = content .newOdfElement(TextTableOfContentElement.class); textTableOfContent.setTextNameAttribute("Table of Contents"); textTableOfContent.setTextProtectedAttribute(true); TextTableOfContentSourceElement textTableOfContentSource = textTableOfContent .newTextTableOfContentSourceElement(); textTableOfContentSource.setTextOutlineLevelAttribute(10); textTableOfContentSource.setTextUseIndexMarksAttribute(true); TextIndexTitleTemplateElement textIndexTitleTemplate = textTableOfContentSource .newTextIndexTitleTemplateElement(); textIndexTitleTemplate .setTextStyleNameAttribute("Contents_20_Heading"); textIndexTitleTemplate.setTextContent("Table of Contents"); for (int i = 1; i <= 10; i++) { TextTableOfContentEntryTemplateElement textTableOfContentEntryTemplate = textTableOfContentSource .newTextTableOfContentEntryTemplateElement(i, "Contents_20_" + i); TextIndexEntryLinkStartElement TextIndexEntryLinkStart = textTableOfContentEntryTemplate .newTextIndexEntryLinkStartElement(); TextIndexEntryLinkStart .setTextStyleNameAttribute("Index_20_Link"); textTableOfContentEntryTemplate .newTextIndexEntryChapterElement(); textTableOfContentEntryTemplate.newTextIndexEntryTextElement(); TextIndexEntryTabStopElement TextIndexEntryTabStop = textTableOfContentEntryTemplate .newTextIndexEntryTabStopElement("right"); TextIndexEntryTabStop.setStyleLeaderCharAttribute("."); textTableOfContentEntryTemplate .newTextIndexEntryPageNumberElement(); textTableOfContentEntryTemplate .newTextIndexEntryLinkEndElement(); } TextIndexBodyElement textIndexBody = textTableOfContent .newTextIndexBodyElement(); TextIndexTitleElement TextIndexTitle = textIndexBody .newTextIndexTitleElement("Table of Contents_Head"); TextPElement texp = TextIndexTitle.newTextPElement(); texp.setTextStyleNameAttribute("Contents_20_Heading"); texp.setTextContent("Table of Contents"); Iterator paragraphIterator = getParagraphIterator(); while (paragraphIterator.hasNext()) { Paragraph paragraph = paragraphIterator.next(); String text = paragraph.getTextContent(); String stylename = paragraph.getStyleName(); // Outline support if (paragraph.isHeading()) { int headingLevel = paragraph.getHeadingLevel(); if (stylename.length() <= 0) { stylename = "Contents_20_" + headingLevel; } ceateIndexBodyEntry(textIndexBody, stylename, text); } // end of Outline support // Index Makes support TextParagraphElementBase podf = paragraph.getOdfElement(); NodeList cns = podf.getChildNodes(); for (int i = 0; i < cns.getLength(); i++) { Node node = cns.item(i); if (node instanceof TextTocMarkElement) { TextTocMarkElement textTocMarkElement = (TextTocMarkElement) node; text = textTocMarkElement.getTextStringValueAttribute(); int headingLevel = textTocMarkElement .getTextOutlineLevelAttribute(); stylename = "Contents_20_" + headingLevel; ceateIndexBodyEntry(textIndexBody, stylename, text); } if (node instanceof TextTocMarkStartElement) { TextTocMarkStartElement textTocMarkStartElement = (TextTocMarkStartElement) node; Node tmp = node.getNextSibling(); while (!(tmp instanceof Text)) { tmp = node.getNextSibling(); } text = tmp.getTextContent(); int headingLevel = textTocMarkStartElement .getTextOutlineLevelAttribute(); stylename = "Contents_20_" + headingLevel; ceateIndexBodyEntry(textIndexBody, stylename, text); } } // end of Index Makes support } if (before) { rootNode.insertBefore(textTableOfContent, refparagraphNode); } else { // Insert TOC after the refParagraph Node refNextNode = refparagraphNode.getNextSibling(); if (refNextNode == null) { rootNode.appendChild(textTableOfContent); } else { rootNode.insertBefore(textTableOfContent, refNextNode); } } return textTableOfContent; } catch (Exception e) { Logger.getLogger(TextDocument.class.getName()).log(Level.SEVERE, "Failed to create Default TOC", e); throw new RuntimeException("Failed to create Default TOC", e); } } private void ceateIndexBodyEntry(TextIndexBodyElement textIndexBody, String stylename, String text) { TextPElement textp = textIndexBody.newTextPElement(); textp.setTextStyleNameAttribute(stylename); textp.newTextNode(text); textp.newTextTabElement(); textp.newTextNode("1"); } /** * Create a new Table Of Content to this document before the reference * paragraph. The additional paragraph styles list will be included in the * TOC. Because until you do a full layout of the document, taking into * account font metrics,line breaking algorithms, hyphenation, image * positioning, "orphan and widow" rules, etc., you don't know what content * is on which page. So all the page numbers in TOC are be set value "1". * Please update the page numbers from AOO Menus: Tools->Update->All Indexes * and Tables. If additionalStyle is null then call createDefaultTOC(). * * @param refParagraph * the reference paragraph before where the TOC inserted. * @param additionalStyle * the additional paragraph styles that you want to include in * the TOC * @param before * true:insert TOC before the reference paragraph. * false:insert TOC after the reference paragraph. * @since 0.8.6 */ public TextTableOfContentElement createTOCwithStyle(Paragraph refParagraph, TOCStyle additionalStyle, boolean before) { if(refParagraph==null){ Logger.getLogger(TextDocument.class.getName()).log(Level.SEVERE, "Failed to create Default TOC, The refParagraph where the TOC be inserted is null"); throw new RuntimeException("Failed to create Default TOC, The refParagraph where the TOC be inserted is null"); } if (additionalStyle == null) { TextTableOfContentElement textTableOfContentElement = createDefaultTOC(refParagraph, before); return textTableOfContentElement; } HashMap tocstyleList = additionalStyle.getStyle(); if (tocstyleList.isEmpty()) { TextTableOfContentElement textTableOfContentElement =createDefaultTOC(refParagraph, before); return textTableOfContentElement; } Collection tocvalues = tocstyleList.values(); OdfOfficeStyles docstyles = getOrCreateDocumentStyles(); Iterable paragraphStyles = docstyles .getStylesForFamily(OdfStyleFamily.Paragraph); ArrayList pstyle = new ArrayList(); Iterator iterator = paragraphStyles.iterator(); while (iterator.hasNext()) { OdfStyle style = iterator.next(); String name = style.getStyleNameAttribute(); pstyle.add(name); } if (!pstyle.containsAll(tocvalues)) { Logger.getLogger(TextDocument.class.getName()) .log(Level.SEVERE, "Failed to create TOC with Styles. Some of addtional Styles that you want to include in the TOC can't be found in the document.\n" + tocvalues.toString()); throw new RuntimeException( "Failed to create TOC Styles.Some of addtional Styles that you want to include in the TOC can't be found in the document."); } TextTableOfContentElement textTableOfContent =null; // Additional Styles support HashMap tmptocstyleList = new HashMap(); if (!tocstyleList.isEmpty()) { Set key = tocstyleList.keySet(); Iterator it = key.iterator(); while (it.hasNext()) { Integer textOutlineLevelValue = it.next(); String textStyleNameValue = tocstyleList .get(textOutlineLevelValue); tmptocstyleList.put(textStyleNameValue, textOutlineLevelValue); } } // end of Additional Styles support Node refparagraphNode = refParagraph.getOdfElement(); Node rootNode = refparagraphNode.getParentNode(); try { OdfContentDom content = getContentDom(); textTableOfContent = content .newOdfElement(TextTableOfContentElement.class); textTableOfContent.setTextNameAttribute("Table of Contents"); textTableOfContent.setTextProtectedAttribute(true); TextTableOfContentSourceElement textTableOfContentSource = textTableOfContent .newTextTableOfContentSourceElement(); textTableOfContentSource.setTextOutlineLevelAttribute(10); textTableOfContentSource.setTextUseIndexMarksAttribute(true); textTableOfContentSource.setTextUseIndexSourceStylesAttribute(true); TextIndexTitleTemplateElement textIndexTitleTemplate = textTableOfContentSource .newTextIndexTitleTemplateElement(); textIndexTitleTemplate .setTextStyleNameAttribute("Contents_20_Heading"); textIndexTitleTemplate.setTextContent("Table of Contents"); for (int i = 1; i <= 10; i++) { TextTableOfContentEntryTemplateElement textTableOfContentEntryTemplate = textTableOfContentSource .newTextTableOfContentEntryTemplateElement(i, "Contents_20_" + i); TextIndexEntryLinkStartElement TextIndexEntryLinkStart = textTableOfContentEntryTemplate .newTextIndexEntryLinkStartElement(); TextIndexEntryLinkStart .setTextStyleNameAttribute("Index_20_Link"); textTableOfContentEntryTemplate .newTextIndexEntryChapterElement(); textTableOfContentEntryTemplate.newTextIndexEntryTextElement(); TextIndexEntryTabStopElement TextIndexEntryTabStop = textTableOfContentEntryTemplate .newTextIndexEntryTabStopElement("right"); TextIndexEntryTabStop.setStyleLeaderCharAttribute("."); textTableOfContentEntryTemplate .newTextIndexEntryPageNumberElement(); textTableOfContentEntryTemplate .newTextIndexEntryLinkEndElement(); } if (!tocstyleList.isEmpty()) { Set key = tocstyleList.keySet(); Iterator it = key.iterator(); while (it.hasNext()) { Integer textOutlineLevelValue = it.next(); String textStyleNameValue = tocstyleList .get(textOutlineLevelValue); TextIndexSourceStylesElement textIndexSourceStyles = textTableOfContentSource .newTextIndexSourceStylesElement(textOutlineLevelValue); textIndexSourceStyles .newTextIndexSourceStyleElement(textStyleNameValue); } } TextIndexBodyElement textIndexBody = textTableOfContent .newTextIndexBodyElement(); TextIndexTitleElement TextIndexTitle = textIndexBody .newTextIndexTitleElement("Table of Contents_Head"); TextPElement texp = TextIndexTitle.newTextPElement(); texp.setTextStyleNameAttribute("Contents_20_Heading"); texp.setTextContent("Table of Contents"); Iterator paragraphIterator = getParagraphIterator(); while (paragraphIterator.hasNext()) { Paragraph paragraph = paragraphIterator.next(); String text = paragraph.getTextContent(); String stylename = paragraph.getStyleName(); // Outline support if (paragraph.isHeading()) { int headingLevel = paragraph.getHeadingLevel(); if (stylename.length() <= 0) { stylename = "Contents_20_" + headingLevel; } ceateIndexBodyEntry(textIndexBody, stylename, text); } // end of Outline support // Additional Styles support if (tmptocstyleList.containsKey(stylename)) { int headingLevel = tmptocstyleList.get(stylename); stylename = "Contents_20_" + headingLevel; ceateIndexBodyEntry(textIndexBody, stylename, text); } // end of Additional Styles support // Index Makes support TextParagraphElementBase podf = paragraph.getOdfElement(); NodeList cns = podf.getChildNodes(); for (int i = 0; i < cns.getLength(); i++) { Node node = cns.item(i); if (node instanceof TextTocMarkElement) { TextTocMarkElement textTocMarkElement = (TextTocMarkElement) node; text = textTocMarkElement.getTextStringValueAttribute(); int headingLevel = textTocMarkElement .getTextOutlineLevelAttribute(); stylename = "Contents_20_" + headingLevel; ceateIndexBodyEntry(textIndexBody, stylename, text); } if (node instanceof TextTocMarkStartElement) { TextTocMarkStartElement textTocMarkStartElement = (TextTocMarkStartElement) node; Node tmp = node.getNextSibling(); while (!(tmp instanceof Text)) { tmp = node.getNextSibling(); } text = tmp.getTextContent(); int headingLevel = textTocMarkStartElement .getTextOutlineLevelAttribute(); stylename = "Contents_20_" + headingLevel; ceateIndexBodyEntry(textIndexBody, stylename, text); } } // end of Index Makes support } if (before) { rootNode.insertBefore(textTableOfContent, refparagraphNode); } else { // Insert TOC after the refParagraph Node refNextNode = refparagraphNode.getNextSibling(); if (refNextNode == null) { rootNode.appendChild(textTableOfContent); } else { rootNode.insertBefore(textTableOfContent, refNextNode); } } return textTableOfContent; } catch (Exception e) { Logger.getLogger(TextDocument.class.getName()).log(Level.SEVERE, "Failed to create Default TOC", e); throw new RuntimeException("Failed to create Default TOC", e); } } /** * Copy a Paragraph and insert it before or after the Reference Paragraph in the text document, whether the * Paragraph is in this document or in a different document. * * @param referenceParagraph * - where the Paragraph be inserted * @param sourceParagraph * - the Paragraph which will be copied * @param before * true:insert Paragraph before the reference paragraph. * false:insert Paragraph after the reference paragraph. */ public Paragraph insertParagraph(Paragraph referenceParagraph, Paragraph sourceParagraph,boolean before) { boolean isForeignNode = false; try { Node refparagraphNode = referenceParagraph.getOdfElement(); if (sourceParagraph.getOdfElement().getOwnerDocument() != getContentDom()) isForeignNode = true; TextParagraphElementBase oldParagraphEle = sourceParagraph.getOdfElement(); TextParagraphElementBase newParagraphEle = (TextParagraphElementBase) oldParagraphEle.cloneNode(true); if (isForeignNode) copyForeignStyleRef(sourceParagraph.getOdfElement(), sourceParagraph.getOwnerDocument()); if (isForeignNode) // not in a same document newParagraphEle = (TextParagraphElementBase) cloneForeignElement(newParagraphEle, getContentDom(), true); if (before) { refparagraphNode.getParentNode().insertBefore(newParagraphEle, refparagraphNode); } else { // Insert Paragraph after the refParagraph Node refNextNode = refparagraphNode.getNextSibling(); if (refNextNode == null) { refparagraphNode.getParentNode().appendChild(newParagraphEle); } else { refparagraphNode.getParentNode().insertBefore(newParagraphEle, refNextNode); } } return Paragraph.getInstanceof(newParagraphEle); } catch (Exception e) { Logger.getLogger(TextDocument.class.getName()).log(Level.SEVERE, null, e); } return null; } /** * Copy a Table and insert it before or after the Reference Paragraph in the text document, whether the * Table is in this TextDocument or in a different Document. * * @param referenceParagraph * - where the Paragraph be inserted * @param sourceParagraph * - the Paragraph which will be copied * @param before * true:insert Paragraph before the reference paragraph. * false:insert Paragraph after the reference paragraph. */ public Table insertTable(Paragraph referenceParagraph, Table sourceTable,boolean before) { Document ownDocument = sourceTable.getOwnerDocument(); TableTableElement newTEle = (TableTableElement)insertOdfElement(referenceParagraph.getOdfElement(),ownDocument,sourceTable.getOdfElement(),before); Table table = Table.getInstance(newTEle); return table; } /** * Copy a OdfElement and insert it before or after the Reference OdfElement in the TextDocument, whether the * OdfElement is in this TextDocument or in a different Document. * * @param referenceOdfElement * - where the OdfElement be inserted * @param sourceDocument * - the source Document which contain the sourceOdfElement * @param sourceOdfElement * - the OdfElement which will be copied * @param before * true:insert OdfElement before the reference OdfElement. * false:insert OdfElement after the reference OdfElement. */ public OdfElement insertOdfElement(OdfElement referenceOdfElement,Document sourceDocument ,OdfElement sourceOdfElement,boolean before) { boolean isForeignNode = false; try { if (sourceOdfElement.getOwnerDocument() != getContentDom()) isForeignNode = true; OdfElement newOdfElement = (OdfElement) sourceOdfElement.cloneNode(true); if (isForeignNode) { copyForeignStyleRef(newOdfElement, sourceDocument); copyLinkedRef(newOdfElement); newOdfElement = (OdfElement) cloneForeignElement(newOdfElement, getContentDom(), true); } if (before) { referenceOdfElement.getParentNode().insertBefore(newOdfElement, referenceOdfElement); } else { // Insert newOdfElement after the referenceOdfElement Node refNextNode = referenceOdfElement.getNextSibling(); if (refNextNode == null) { referenceOdfElement.getParentNode().appendChild(newOdfElement); } else { referenceOdfElement.getParentNode().insertBefore(newOdfElement, refNextNode); } } return newOdfElement; } catch (Exception e) { Logger.getLogger(TextDocument.class.getName()).log(Level.SEVERE, null, e); } return null; } private OdfElement insertOdfElementwithoutstyle(OdfElement referenceOdfElement,Document sourceDocument ,OdfElement sourceOdfElement,boolean before) { try { OdfElement newOdfElement = (OdfElement) sourceOdfElement.cloneNode(true); newOdfElement = (OdfElement) cloneForeignElement(newOdfElement, getContentDom(), true); if (before) { referenceOdfElement.getParentNode().insertBefore(newOdfElement, referenceOdfElement); } else { // Insert newOdfElement after the referenceOdfElement Node refNextNode = referenceOdfElement.getNextSibling(); if (refNextNode == null) { referenceOdfElement.getParentNode().appendChild(newOdfElement); } else { referenceOdfElement.getParentNode().insertBefore(newOdfElement, refNextNode); } } return newOdfElement; } catch (Exception e) { Logger.getLogger(TextDocument.class.getName()).log(Level.SEVERE, null, e); } return null; } /** * Copy text content of the source TextDocument and insert it to the current TextDocument * after the reference Paragraph, with Styles or without Styles. * * @param sourceDocument * the source TextDocument * @param referenceParagraph * where the text content of the source TextDocument be inserted * @param isCopyStyle * true:copy the styles in source document to current TextDocment. * false:don't copy the styles in source document to current TextDocment. */ public void insertContentFromDocumentAfter(TextDocument sourceDocument, Paragraph referenceParagraph, boolean isCopyStyle){ try { OfficeTextElement sroot = sourceDocument.getContentRoot(); NodeList clist = sroot.getChildNodes(); for (int i=(clist.getLength()-1); i>=0; i--) { OdfElement node = (OdfElement) clist.item(i); if(isCopyStyle){ insertOdfElement(referenceParagraph.getOdfElement(), sourceDocument, node, false); } else { insertOdfElementwithoutstyle(referenceParagraph.getOdfElement(), sourceDocument, node, false); } } } catch (Exception e) { Logger.getLogger(TextDocument.class.getName()).log(Level.SEVERE, null, e); } } /** * Copy text content of the source TextDocument and insert it to the current TextDocument * before the reference Paragraph, with Styles or without Styles. * * @param srcDoc * the source TextDocument * @param referenceParagraph * where the text content of the source TextDocument be inserted * @param isCopyStyle * true:copy the styles in source document to current TextDocment. * false:don't copy the styles in source document to current TextDocment. */ public void insertContentFromDocumentBefore(TextDocument sourceDocument, Paragraph referenceParagraph, boolean isCopyStyle){ try { OfficeTextElement sroot = sourceDocument.getContentRoot(); NodeList clist = sroot.getChildNodes(); for (int i = 0; i < clist.getLength(); i++) { OdfElement node = (OdfElement) clist.item(i); if(isCopyStyle){ insertOdfElement(referenceParagraph.getOdfElement(), sourceDocument, node, true); } else { insertOdfElementwithoutstyle(referenceParagraph.getOdfElement(), sourceDocument, node, true); } } } catch (Exception e) { Logger.getLogger(TextDocument.class.getName()).log(Level.SEVERE, null, e); } } private FormContainerImpl getFormContainerImpl() { if (formContainerImpl == null) { formContainerImpl = new FormContainerImpl(); } return formContainerImpl; } private class FormContainerImpl extends AbstractFormContainer { public OfficeFormsElement getFormContainerElement() { OfficeFormsElement forms = null; try { OfficeTextElement root = getContentRoot(); forms = OdfElement.findFirstChildNode(OfficeFormsElement.class, root); if (forms == null) { Node firstChild = root.getFirstChild(); OfficeFormsElement officeForms = ((OdfFileDom) getContentDom()) .newOdfElement(OfficeFormsElement.class); forms = (OfficeFormsElement) root.insertBefore(officeForms, firstChild); } return forms; } catch (Exception e) { Logger.getLogger(TextDocument.class.getName()).log( Level.SEVERE, null, e); } return forms; } } /** * Create a form with specified name in this text document. * * @see FormContainer#createForm(String) */ public Form createForm(String name) { return getFormContainerImpl().createForm(name); } /** * Get a form iterator to traverse all the forms in this document. * * @see FormContainer#getFormIterator() */ public Iterator

getFormIterator() { return getFormContainerImpl().getFormIterator(); } /** * Remove a form with the specified name in this document. * * @see FormContainer#removeForm(Form) */ public boolean removeForm(Form form) { return getFormContainerImpl().removeForm(form); } // @Override public Form getFormByName(String name) { return getFormContainerImpl().getFormByName(name); } // @Override public OfficeFormsElement getFormContainerElement() { return getFormContainerImpl().getFormContainerElement(); } // @Override public boolean getApplyDesignMode() { return getFormContainerImpl().getApplyDesignMode(); } // @Override public boolean getAutomaticFocus() { return getFormContainerImpl().getAutomaticFocus(); } // @Override public void setApplyDesignMode(boolean isDesignMode) { getFormContainerImpl().setApplyDesignMode(isDesignMode); } // @Override public void setAutomaticFocus(boolean isAutoFocus) { getFormContainerImpl().setAutomaticFocus(isAutoFocus); } // @Override public Control createDrawControl() { OdfElement parent = this.getDrawControlContainerElement(); OdfFileDom ownerDom = (OdfFileDom) parent.getOwnerDocument(); DrawControlElement element = ownerDom .newOdfElement(DrawControlElement.class); Node refChild = OdfElement.findFirstChildNode( TextSequenceDeclsElement.class, parent); parent.insertBefore(element, refChild.getNextSibling()); Control control = new Control(element); Component.registerComponent(control, element); return control; } // @Override public OdfElement getDrawControlContainerElement() { OdfElement element = null; try { element = this.getContentRoot(); } catch (Exception e) { Logger.getLogger(TextDocument.class.getName()).log(Level.SEVERE, null, e); } return element; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy