diff --git a/source/distro/changelog.txt b/source/distro/changelog.txt
index de4e73a..3e4a1c7 100644
--- a/source/distro/changelog.txt
+++ b/source/distro/changelog.txt
@@ -1,124 +1,7 @@
-Changelog for Writer2LaTeX version 1.2 -> 1.4
+Changelog for Writer2LaTeX version 1.4 -> 1.6
----------- version 1.4 beta ----------
+---------- version 1.5.1 ----------
-[w4l] Zotero BibTeX exporter is updated to the latest version
+[w2x] Added toolbar with two buttons to publish directly to XHTML/EPUB.
-[all] Build file is now set up to cross compile for java 6
-
-[w2x] If the export dialogs are loaded with a setting for scaling or column_scaling of 1% or less, the value
- is reset to 100%. This is a workaround for an obscure bug in the extension manager, which in some cases sets
- the value to 1% if the export is used right after installation.
-
-[w2x] Bugfix: The help button on the EPUB export dialog now works
-
-[w2x] Bugfix: Avoid null pointer exception in HTML5 export if embed_svg is true and an image is used more than once
-
-[all] An image that is used more than once in the source document is now only exported once. This was already the
- case for the package format (since 1.3.2), but now also for flat XML.
-
-[w2x] The The option inline_svg has been renamed (again) to embed_svg, and the default is changed to false
-
-[w2x] The experimental option zen_hack has been removed
-
-[w2x] For templates it is no longer required that the footer, header and panel are contained in a div element.
- This allows for HTML5 code like . The default header and footer
- are now created with header+nav and footer+nav elements if the target format is HTML5.
-
----------- version 1.3.2 alpha ----------
-
-[w2l] Two or more span elements in a row which generates identical formatting in LaTeX are now merged.
- This avoids constructs like \textbf{this is }\textbf{bold}.
-
-[w2l] Optimization: The SimpleDomBuilder now merges text nodes
-
-[w2l] Replace usage of StringBuffer with StringBuilder everywhere (marginal optimization)
-
-[w2l] The standard configurations pdfprint.xml and pdfscreen.xml no longer requires ooomath.sty
-
-[w2l] A bookmark in a heading no longer results in an optional argument to \section commands
-
-[w2l] New option display_hidden_text (default false) to toggle whether or not hidden text should be included in
- the export. In the export filter, this option can be toggled in the export options dialog.
-
-[w2l] Bugfix (StarMath conversion): The five colors red, green, blue, magenta and yellow is now exported to the
- correct dark colors rather than the previous bright colors (the colors white, black and yellow are unchanged)
-
-[w2x] If a border has a width which is equivalent to less that 1px, it is now exported with the width 1px.
- This fixes an issue with some browsers, that would render the border invisible.
-
-[w2x] Two or more span elements in a row with identical attributes are now merged
-
-[all] Filters: Appended [Writer2LaTeX] or [Writer2xhtml] to all filter UI names to make them more visible
-
-[w2l] Bugfix: Avoid null pointer exception caused by list styles in some cases
-
-[w2x] Bugfix: EPUB export filter works again (was broken in 1.3.1)
-
-[w2x] Bugfix: Text boxes are no longer lost if within a paragraph
-
-[w2x] SVG support in HTML5 is now finished: Images in SVG format are kept in the original format.
- Other vector images are converted to SVG (filter only). This only works with recent versions of the office
- (LO 4.2 and AOO 4.1 are known to work). The option use_svg has been renamed to inline_svg. If set to
- true (default) inline SVG is used, if set to false, external SVG-files (img-elements) are used.
- In the UI, this setting can be found on the options page Writer2xhtml - Content.
-
-[all] If an image image cannot be converted to an acceptable format, the optional alternative image will now be tried
-
-[all] Bugfix: Avoid null pointer exception if a table has no defined table width
-
-[w2l] Bugfix (StarMath conversion): Protect the character [ after \\ in gather and matrix environments
-
-[w2l] Bugfix: Protect the character [ after \\ in tables
-
-[w2l] Bugfix (StarMath conversion): Usage of \multiscripts and \mathoverstrike now loads the required calc.sty
-
-[w2l] Bugfix (StarMath conversion): Do not create display equations in table cells
-
-[w2l] Bugfix (StarMath conversion): Set the counter MaxMatrixCols if there are matrices with more than 10 columns
-
-[w2l] Bugfix (StarMath conversion): Add braces if the argument to a command is a space, e.g. \text{ }
-
-[all] Refactored and optimized memory usage of image conversion
-
-[all] Refactored and rearranged some code; in particular the last remaining bits of the old xmerge framework has been removed
-
-[all] Optimized reading of package format: The settings.xml files are not parsed and the unused parts of the ZIP file are disposed
-
----------- version 1.3.1 alpha ----------
-
-[w2x] Starting with version 4.2, LibreOffice exports display="math" on display equations. This attribute is now
- removed if a display equation is used inline in the source document.
-
-[w2x] Support for the obsolete output format XHTML+MahtML+XSL has been removed (replaced by MathJax). As a consequence
- the option xslt_path has been removed. Also the vacant spot in the export dialog is now used for the option use_mathjax
- (only active for XHTML+MathML and HTML5)
-
-[all] Added support for TexMaths equations in LaTeX, XHTML+MathML and HTML5 (the last two only if use_mathjax=true)
-
-[all] The command line application now gives an explanation if the source file is not in ODF format
-
-[all] Bugfix: Fixed typo that caused writer2latex.office.MIMETypes.getMagicMIMEType() to fail in some cases
-
-[w2x] The option ignore_table_dimensions has been replaced by a new option table_size with values none (do not export table
- dimensions), relative (always use relative width) and auto (use the formatting of the source document):
- If set to true, all tables are exported with relative width, even if they have an absolute width in the source document
-
-[w2x] New boolean option use_mathjax (default false): If set to true and export format is XHTML+MATHML or HTML5,
- documents will load the MathJax JavaScript library for rendering of formulas (otherwise the document will rely
- on native MathML support in the browser)
-
-[w2x] New boolean option use_svg (default false): If set to true and export format is HTML5, vector graphics are exported as
- inline SVG, if possible
-
-[w2x] Added support for HTML5 as export type (the ConverterFactory understands the pseudo-MIME type text/html5).
- The converter creates polyglot HTML5 documents, i.e. documents will be conforming to HTML5 as well as XML standards.
-
-[all] Optimized the parsing of the source document saving some time and space (several intermediate steps and large byte arrays
- are now avoided)
-
-[all] API change: The converters can now convert directly from a DOM tree
-
-[all] Removed unused code in writer2latex.xmerge
-
-[w2x] Moved localized strings to .properties files
\ No newline at end of file
+[all] Filter: Refactored filter code, the actual conversion has been separated from the XExportFilter implementation
\ No newline at end of file
diff --git a/source/java/org/openoffice/da/comp/w2lcommon/filter/ExportFilterBase.java b/source/java/org/openoffice/da/comp/w2lcommon/filter/ExportFilterBase.java
index a67726f..07dd69a 100644
--- a/source/java/org/openoffice/da/comp/w2lcommon/filter/ExportFilterBase.java
+++ b/source/java/org/openoffice/da/comp/w2lcommon/filter/ExportFilterBase.java
@@ -20,38 +20,24 @@
*
* All Rights Reserved.
*
- * Version 1.4 (2014-08-28)
+ * Version 1.6 (2014-10-06)
*
*/
package org.openoffice.da.comp.w2lcommon.filter;
-import com.sun.star.lib.uno.adapter.XOutputStreamToOutputStreamAdapter;
-
-import com.sun.star.io.XInputStream;
-import com.sun.star.io.XOutputStream;
-import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.lang.XServiceName;
import com.sun.star.lang.XTypeProvider;
-import com.sun.star.uno.AnyConverter;
-import com.sun.star.ucb.XSimpleFileAccess2;
import com.sun.star.uno.Type;
-import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.xml.sax.XDocumentHandler;
import com.sun.star.xml.XExportFilter;
import org.openoffice.da.comp.w2lcommon.helper.MessageBox;
-import writer2latex.api.Converter;
-import writer2latex.api.ConverterFactory;
-import writer2latex.api.OutputFile;
-import writer2latex.util.Misc;
import writer2latex.util.SimpleDOMBuilder;
import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Iterator;
/** This class provides an abstract UNO component which implements an XExportFilter.
@@ -74,96 +60,29 @@ XTypeProvider {
/** Filter name to include in error messages */
public String __displayName = "";
- private static XComponentContext xComponentContext = null;
- protected static XMultiServiceFactory xMSF;
+ private XComponentContext xComponentContext = null;
private SimpleDOMBuilder domBuilder = new SimpleDOMBuilder();
- private static XOutputStream xos = null;
- private static String sdMime=null;
- private static String sURL="";
+ private UNOConverter converter = null;
- private Object filterData;
- private XSimpleFileAccess2 sfa2;
-
- /** We need to get the Service Manager from the Component context to
- * instantiate certain services, hence this constructor.
- * The subclass must override this to set xMSF properly from the registration class
+ /** Construct a new ExportFilterBase from a given component context
+ *
+ * @param xComponentContext the component context used to instantiate new UNO services
*/
- public ExportFilterBase(XComponentContext xComponentContext1) {
- xComponentContext = xComponentContext1;
- xMSF = null;
+ public ExportFilterBase(XComponentContext xComponentContext) {
+ this.xComponentContext = xComponentContext;
}
- // Utility method:
-
- String getFileName(String origName) {
- String name=null;
- if (origName !=null) {
- if(origName.equalsIgnoreCase(""))
- name = "OutFile";
- else {
- if (origName.lastIndexOf("/")>=0) {
- origName=origName.substring(origName.lastIndexOf("/")+1,origName.length());
- }
- if (origName.lastIndexOf(".")>=0) {
- name = origName.substring(0,(origName.lastIndexOf(".")));
- }
- else {
- name=origName;
- }
- }
- }
- else{
- name = "OutFile";
- }
-
- return name;
- }
-
+ // ---------------------------------------------------------------------------
// Implementation of XExportFilter:
public boolean exporter(com.sun.star.beans.PropertyValue[] aSourceData,
- java.lang.String[] msUserData) throws com.sun.star.uno.RuntimeException{
- sURL=null;
- filterData = null;
-
- // Get user data from configuration (type detection)
- //String udConvertClass=msUserData[0];
- //String udImport =msUserData[2];
- //String udExport =msUserData[3];
- sdMime = msUserData[5];
-
- // Get source data (only the OutputStream and the URL are actually used)
- com.sun.star.beans.PropertyValue[] pValue = aSourceData;
- for (int i = 0 ; i < pValue.length; i++) {
- try{
- if (pValue[i].Name.compareTo("OutputStream")==0){
- xos=(com.sun.star.io.XOutputStream)AnyConverter.toObject(new Type(com.sun.star.io.XOutputStream.class), pValue[i].Value);
- }
- //if (pValue[i].Name.compareTo("FileName")==0){
- // sFileName=(String)AnyConverter.toObject(new Type(java.lang.String.class), pValue[i].Value);
- //}
- if (pValue[i].Name.compareTo("URL")==0){
- sURL=(String)AnyConverter.toObject(new Type(java.lang.String.class), pValue[i].Value);
- }
- //if (pValue[i].Name.compareTo("Title")==0){
- // title=(String)AnyConverter.toObject(new Type(java.lang.String.class), pValue[i].Value);
- //}
- if (pValue[i].Name.compareTo("FilterData")==0) {
- filterData = pValue[i].Value;
- }
- }
- catch(com.sun.star.lang.IllegalArgumentException AnyExec){
- System.err.println("\nIllegalArgumentException "+AnyExec);
- }
- }
-
- if (sURL==null){
- sURL="";
- }
-
+ java.lang.String[] msUserData) {
+ // Create a suitable converter
+ converter = new UNOConverter(aSourceData, xComponentContext);
return true;
}
+ // ---------------------------------------------------------------------------
// Implementation of XDocumentHandler:
// A flat XML DOM tree is created by the SAX events and finally converted
@@ -173,7 +92,7 @@ XTypeProvider {
public void endDocument()throws com.sun.star.uno.RuntimeException {
try{
- convert(domBuilder.getDOM(),xos);
+ converter.convert(domBuilder.getDOM());
}
catch (IOException e){
MessageBox msgBox = new MessageBox(xComponentContext);
@@ -189,8 +108,6 @@ XTypeProvider {
}
}
-
-
public void startElement (String sTagName, com.sun.star.xml.sax.XAttributeList xAttribs) {
domBuilder.startElement(sTagName);
int nLen = xAttribs.getLength();
@@ -216,112 +133,8 @@ XTypeProvider {
public void setDocumentLocator(com.sun.star.xml.sax.XLocator xLocator){
}
-
- // This is the actual conversion method, using Writer2LaTeX to convert
- // the flat XML from the DOM, and writing the result
- // to the XOutputStream. The XMLExporter does not support export to
- // compound documents with multiple output files; hence the main file
- // is written to the XOutStream and other files are written using UCB.
-
- public void convert (org.w3c.dom.Document dom,com.sun.star.io.XOutputStream exportStream)
- throws com.sun.star.uno.RuntimeException, IOException {
- // Create converter and supply it with filter data and a suitable graphic converter
- Converter converter = ConverterFactory.createConverter(sdMime);
- if (converter==null) {
- throw new com.sun.star.uno.RuntimeException("Failed to create converter to "+sdMime);
- }
- if (filterData!=null) {
- FilterDataParser fdp = new FilterDataParser(xComponentContext);
- fdp.applyFilterData(filterData,converter);
- }
- converter.setGraphicConverter(new GraphicConverterImpl(xComponentContext));
-
- // Do conversion. The base name is take from the URL provided by the office
- Iterator docEnum = converter.convert(dom,Misc.makeFileName(getFileName(sURL)),true).iterator();
-
- if (docEnum.hasNext()) {
- // The master document is written to the XOutStream supplied by the XMLFilterAdaptor
- XOutputStreamToOutputStreamAdapter newxos =new XOutputStreamToOutputStreamAdapter(exportStream);
- docEnum.next().write(newxos);
- newxos.flush();
- newxos.close();
-
- if (docEnum.hasNext() && sURL.startsWith("file:")) {
- // Additional files are written directly using UCB
- // Initialize the file access (used to write all additional output files)
- sfa2 = null;
- try {
- Object sfaObject = xComponentContext.getServiceManager().createInstanceWithContext(
- "com.sun.star.ucb.SimpleFileAccess", xComponentContext);
- sfa2 = (XSimpleFileAccess2) UnoRuntime.queryInterface(XSimpleFileAccess2.class, sfaObject);
- }
- catch (com.sun.star.uno.Exception e) {
- // failed to get SimpleFileAccess service (should not happen)
- }
-
- if (sfa2!=null) {
- // Remove the file name part of the URL
- String sNewURL = null;
- if (sURL.lastIndexOf("/")>-1) {
- // Take the URL up to and including the last slash
- sNewURL = sURL.substring(0,sURL.lastIndexOf("/")+1);
- }
- else {
- // The URL does not include a path; this should not really happen,
- // but in this case we will write to the current default directory
- sNewURL = "";
- }
-
- while (docEnum.hasNext()) {
- OutputFile docOut = docEnum.next();
- // Get the file name and the (optional) directory name
- String sFullFileName = Misc.makeHref(docOut.getFileName());
- String sDirName = "";
- String sFileName = sFullFileName;
- int nSlash = sFileName.indexOf("/");
- if (nSlash>-1) {
- sDirName = sFileName.substring(0,nSlash);
- sFileName = sFileName.substring(nSlash+1);
- }
-
- try{
- // Create subdirectory if required
- if (sDirName.length()>0 && !sfa2.exists(sNewURL+sDirName)) {
- sfa2.createFolder(sNewURL+sDirName);
- }
-
- // writeFile demands an InputStream, so we need a pipe
- Object xPipeObj=xMSF.createInstance("com.sun.star.io.Pipe");
- XInputStream xInStream = (XInputStream) UnoRuntime.queryInterface(XInputStream.class, xPipeObj );
- XOutputStream xOutStream = (XOutputStream) UnoRuntime.queryInterface(XOutputStream.class, xPipeObj );
- OutputStream outStream = new XOutputStreamToOutputStreamAdapter(xOutStream);
- // Feed the pipe with content...
- docOut.write(outStream);
- outStream.flush();
- outStream.close();
- xOutStream.closeOutput();
- // ...and then write the content to the URL
- sfa2.writeFile(sNewURL+sFullFileName,xInStream);
- }
- catch (Throwable e){
- MessageBox msgBox = new MessageBox(xComponentContext);
- msgBox.showMessage(__displayName+": Error writing files",
- e.toString()+" at "+e.getStackTrace()[0].toString());
- }
- }
- }
- }
- }
- else {
- // The converter did not produce any files (should not happen)
- MessageBox msgBox = new MessageBox(xComponentContext);
- msgBox.showMessage(__displayName+": Conversion failed","Internal error");
- }
- }
-
-
+ // ---------------------------------------------------------------------------
// Implement methods from interface XTypeProvider
- // Implementation of XTypeProvider
public com.sun.star.uno.Type[] getTypes() {
Type[] typeReturn = {};
@@ -349,11 +162,13 @@ XTypeProvider {
return( byteReturn );
}
+ // ---------------------------------------------------------------------------
// Implement method from interface XServiceName
public String getServiceName() {
return( __serviceName );
}
+ // ---------------------------------------------------------------------------
// Implement methods from interface XServiceInfo
public boolean supportsService(String stringServiceName) {
return( stringServiceName.equals( __serviceName ) );
@@ -368,5 +183,4 @@ XTypeProvider {
return( stringSupportedServiceNames );
}
-
}
diff --git a/source/java/org/openoffice/da/comp/w2lcommon/filter/UNOConverter.java b/source/java/org/openoffice/da/comp/w2lcommon/filter/UNOConverter.java
new file mode 100644
index 0000000..c5c6c66
--- /dev/null
+++ b/source/java/org/openoffice/da/comp/w2lcommon/filter/UNOConverter.java
@@ -0,0 +1,255 @@
+/************************************************************************
+ *
+ * UNOConverter.java
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Copyright: 2002-2014 by Henrik Just
+ *
+ * All Rights Reserved.
+ *
+ * Version 1.6 (2014-10-07)
+ *
+ */
+package org.openoffice.da.comp.w2lcommon.filter;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.w3c.dom.Document;
+
+import writer2latex.api.Converter;
+import writer2latex.api.ConverterFactory;
+import writer2latex.api.ConverterResult;
+import writer2latex.api.OutputFile;
+import writer2latex.util.Misc;
+
+import com.sun.star.beans.PropertyValue;
+import com.sun.star.io.XInputStream;
+import com.sun.star.io.XOutputStream;
+import com.sun.star.lib.uno.adapter.XInputStreamToInputStreamAdapter;
+import com.sun.star.lib.uno.adapter.XOutputStreamToOutputStreamAdapter;
+import com.sun.star.ucb.XSimpleFileAccess2;
+import com.sun.star.uno.AnyConverter;
+import com.sun.star.uno.Type;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+
+/** This class provides conversion using UNO:
+ * Graphics conversion is done using appropriate UNO services.
+ * Files are written to an URL using UCB.
+ * The document source document can be provided as an XInputStream
or as a DOM tree
+ */
+public class UNOConverter {
+ private XComponentContext xComponentContext;
+ private Converter converter;
+ private String sTargetFormat = null;
+ private XOutputStream xos = null;
+ private String sURL = null;
+
+ /** Construct a new UNODocumentConverter from an array of arguments
+ *
+ * @param xComponentContext the component context used to instantiate new UNO services
+ * @param lArguments arguments providing FilterName, URL, OutputStream (optional) and FilterData (optional)
+ */
+ public UNOConverter(PropertyValue[] lArguments, XComponentContext xComponentContext) {
+ this.xComponentContext = xComponentContext;
+
+ // Create mapping from filter names to target media types
+ HashMap filterNames = new HashMap();
+ filterNames.put("org.openoffice.da.writer2latex","application/x-latex");
+ filterNames.put("org.openoffice.da.writer2bibtex","application/x-bibtex");
+ filterNames.put("org.openoffice.da.writer2xhtml","text/html");
+ filterNames.put("org.openoffice.da.writer2xhtml11","application/xhtml11");
+ filterNames.put("org.openoffice.da.writer2xhtml5","text/html5");
+ filterNames.put("org.openoffice.da.writer2xhtml.mathml","application/xhtml+xml");
+ filterNames.put("org.openoffice.da.writer2xhtml.epub","application/epub+zip");
+ filterNames.put("org.openoffice.da.calc2xhtml","text/html");
+ filterNames.put("org.openoffice.da.calc2xhtml11","application/xhtml11");
+ filterNames.put("org.openoffice.da.calc2xhtml5","text/html5");
+
+ // Get the arguments
+ Object filterData = null;
+ PropertyValue[] pValue = lArguments;
+ for (int i = 0 ; i < pValue.length; i++) {
+ try {
+ if (pValue[i].Name.compareTo("FilterName")==0) {
+ String sFilterName = (String)AnyConverter.toObject(new Type(String.class), pValue[i].Value);
+ if (filterNames.containsKey(sFilterName)) {
+ sTargetFormat = filterNames.get(sFilterName);
+ }
+ else {
+ sTargetFormat = sFilterName;
+ }
+ }
+ if (pValue[i].Name.compareTo("OutputStream")==0){
+ xos = (XOutputStream)AnyConverter.toObject(new Type(XOutputStream.class), pValue[i].Value);
+ }
+ if (pValue[i].Name.compareTo("URL")==0){
+ sURL = (String)AnyConverter.toObject(new Type(String.class), pValue[i].Value);
+ }
+ if (pValue[i].Name.compareTo("FilterData")==0) {
+ filterData = pValue[i].Value;
+ }
+ }
+ catch(com.sun.star.lang.IllegalArgumentException AnyExec){
+ System.err.println("\nIllegalArgumentException "+AnyExec);
+ }
+ }
+ if (sURL==null){
+ sURL="";
+ }
+
+ // Create converter and supply it with filter data and a suitable graphic converter
+ converter = ConverterFactory.createConverter(sTargetFormat);
+ if (converter==null) {
+ throw new com.sun.star.uno.RuntimeException("Failed to create converter to "+sTargetFormat);
+ }
+ if (filterData!=null) {
+ FilterDataParser fdp = new FilterDataParser(xComponentContext);
+ fdp.applyFilterData(filterData,converter);
+ }
+ converter.setGraphicConverter(new GraphicConverterImpl(xComponentContext));
+
+ }
+
+ /** Convert a document given by a DOM tree
+ *
+ * @param dom the DOMsource
+ * @throws IOException
+ */
+ public void convert(Document dom) throws IOException {
+ writeFiles(converter.convert(dom, Misc.makeFileName(getFileName(sURL)),true));
+ }
+
+ /** Convert a document given by an XInputStream
+ *
+ * @param xis the input stream
+ * @throws IOException
+ */
+ public void convert(XInputStream xis) throws IOException {
+ InputStream is = new XInputStreamToInputStreamAdapter(xis);
+ writeFiles(converter.convert(is, Misc.makeFileName(getFileName(sURL))));
+ }
+
+ private void writeFiles(ConverterResult result) throws IOException {
+ Iterator docEnum = result.iterator();
+ if (docEnum.hasNext()) {
+ // The master document is written to the supplied XOutputStream, if any
+ if (xos!=null) {
+ XOutputStreamToOutputStreamAdapter newxos =new XOutputStreamToOutputStreamAdapter(xos);
+ docEnum.next().write(newxos);
+ newxos.flush();
+ newxos.close();
+ }
+ // Additional files are written directly using UCB
+ if (docEnum.hasNext() && sURL.startsWith("file:")) {
+ // Initialize the file access (used to write all additional output files)
+ XSimpleFileAccess2 sfa2 = null;
+ try {
+ Object sfaObject = xComponentContext.getServiceManager().createInstanceWithContext(
+ "com.sun.star.ucb.SimpleFileAccess", xComponentContext);
+ sfa2 = (XSimpleFileAccess2) UnoRuntime.queryInterface(XSimpleFileAccess2.class, sfaObject);
+ }
+ catch (com.sun.star.uno.Exception e) {
+ // failed to get SimpleFileAccess service (should not happen)
+ }
+
+ if (sfa2!=null) {
+ // Remove the file name part of the URL
+ String sNewURL = null;
+ if (sURL.lastIndexOf("/")>-1) {
+ // Take the URL up to and including the last slash
+ sNewURL = sURL.substring(0,sURL.lastIndexOf("/")+1);
+ }
+ else {
+ // The URL does not include a path; this should not really happen,
+ // but in this case we will write to the current default directory
+ sNewURL = "";
+ }
+
+ while (docEnum.hasNext()) {
+ OutputFile docOut = docEnum.next();
+ // Get the file name and the (optional) directory name
+ String sFullFileName = Misc.makeHref(docOut.getFileName());
+ String sDirName = "";
+ String sFileName = sFullFileName;
+ int nSlash = sFileName.indexOf("/");
+ if (nSlash>-1) {
+ sDirName = sFileName.substring(0,nSlash);
+ sFileName = sFileName.substring(nSlash+1);
+ }
+
+ try {
+ // Create subdirectory if required
+ if (sDirName.length()>0 && !sfa2.exists(sNewURL+sDirName)) {
+ sfa2.createFolder(sNewURL+sDirName);
+ }
+
+ // writeFile demands an InputStream, so we use a Pipe for the transport
+ Object xPipeObj = xComponentContext.getServiceManager().createInstanceWithContext(
+ "com.sun.star.io.Pipe", xComponentContext);
+ XInputStream xInStream = (XInputStream) UnoRuntime.queryInterface(XInputStream.class, xPipeObj);
+ XOutputStream xOutStream = (XOutputStream) UnoRuntime.queryInterface(XOutputStream.class, xPipeObj);
+ OutputStream outStream = new XOutputStreamToOutputStreamAdapter(xOutStream);
+ // Feed the pipe with content...
+ docOut.write(outStream);
+ outStream.flush();
+ outStream.close();
+ xOutStream.closeOutput();
+ // ...and then write the content to the URL
+ sfa2.writeFile(sNewURL+sFullFileName,xInStream);
+ }
+ catch (Throwable e){
+ throw new IOException("Error writing file "+sFileName+" "+e.getMessage());
+ }
+ }
+ }
+ }
+ }
+ else {
+ // The converter did not produce any files (should not happen)
+ throw new IOException("Conversion failed: Internal error");
+ }
+ }
+
+ private String getFileName(String origName) {
+ String name=null;
+ if (origName !=null) {
+ if(origName.equalsIgnoreCase(""))
+ name = "OutFile";
+ else {
+ if (origName.lastIndexOf("/")>=0) {
+ origName=origName.substring(origName.lastIndexOf("/")+1,origName.length());
+ }
+ if (origName.lastIndexOf(".")>=0) {
+ name = origName.substring(0,(origName.lastIndexOf(".")));
+ }
+ else {
+ name=origName;
+ }
+ }
+ }
+ else{
+ name = "OutFile";
+ }
+
+ return name;
+ }
+
+}
\ No newline at end of file
diff --git a/source/java/org/openoffice/da/comp/writer2latex/W2LExportFilter.java b/source/java/org/openoffice/da/comp/writer2latex/W2LExportFilter.java
index 8d4adc0..3d5a9f8 100644
--- a/source/java/org/openoffice/da/comp/writer2latex/W2LExportFilter.java
+++ b/source/java/org/openoffice/da/comp/writer2latex/W2LExportFilter.java
@@ -16,11 +16,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
- * Copyright: 2002-2009 by Henrik Just
+ * Copyright: 2002-2014 by Henrik Just
*
* All Rights Reserved.
*
- * Version 1.2 (2009-09-06)
+ * Version 1.6 (2014-10-06)
*
*/
@@ -46,7 +46,6 @@ public class W2LExportFilter extends ExportFilterBase {
public W2LExportFilter(XComponentContext xComponentContext1) {
super(xComponentContext1);
- xMSF = W2LRegistration.xMultiServiceFactory;
}
diff --git a/source/java/org/openoffice/da/comp/writer2xhtml/W2XExportFilter.java b/source/java/org/openoffice/da/comp/writer2xhtml/W2XExportFilter.java
index 1f59f07..ae2c1ca 100644
--- a/source/java/org/openoffice/da/comp/writer2xhtml/W2XExportFilter.java
+++ b/source/java/org/openoffice/da/comp/writer2xhtml/W2XExportFilter.java
@@ -16,11 +16,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
- * Copyright: 2002-2009 by Henrik Just
+ * Copyright: 2002-2014 by Henrik Just
*
* All Rights Reserved.
*
- * Version 1.2 (2009-09-06)
+ * Version 1.6 (2014-10-06)
*
*/
@@ -46,7 +46,6 @@ public class W2XExportFilter extends ExportFilterBase {
public W2XExportFilter(XComponentContext xComponentContext1) {
super(xComponentContext1);
- xMSF = W2XRegistration.xMultiServiceFactory;
}
diff --git a/source/java/org/openoffice/da/comp/writer2xhtml/W2XRegistration.java b/source/java/org/openoffice/da/comp/writer2xhtml/W2XRegistration.java
index de9274b..cbc4ce6 100644
--- a/source/java/org/openoffice/da/comp/writer2xhtml/W2XRegistration.java
+++ b/source/java/org/openoffice/da/comp/writer2xhtml/W2XRegistration.java
@@ -20,7 +20,7 @@
*
* All Rights Reserved.
*
- * Version 1.4 (2014-08-18)
+ * Version 1.6 (2014-10-06)
*
*/
@@ -60,7 +60,13 @@ public class W2XRegistration {
XMultiServiceFactory multiFactory, XRegistryKey regKey) {
xMultiServiceFactory = multiFactory;
XSingleServiceFactory xSingleServiceFactory = null;
- if (implName.equals(W2XExportFilter.class.getName()) ) {
+ if (implName.equals(Writer2xhtml.__implementationName) ) {
+ xSingleServiceFactory = FactoryHelper.getServiceFactory(Writer2xhtml.class,
+ Writer2xhtml.__serviceName,
+ multiFactory,
+ regKey);
+ }
+ else if (implName.equals(W2XExportFilter.class.getName()) ) {
xSingleServiceFactory = FactoryHelper.getServiceFactory(W2XExportFilter.class,
W2XExportFilter.__serviceName,
multiFactory,
@@ -124,6 +130,8 @@ public class W2XRegistration {
return
FactoryHelper.writeRegistryServiceInfo(BatchConverter.__implementationName,
BatchConverter.__serviceName, regKey) &
+ FactoryHelper.writeRegistryServiceInfo(Writer2xhtml.__implementationName,
+ Writer2xhtml.__serviceName, regKey) &
FactoryHelper.writeRegistryServiceInfo(W2XExportFilter.__implementationName,
W2XExportFilter.__serviceName, regKey) &
FactoryHelper.writeRegistryServiceInfo(XhtmlOptionsDialog.__implementationName,
diff --git a/source/java/org/openoffice/da/comp/writer2xhtml/Writer2xhtml.java b/source/java/org/openoffice/da/comp/writer2xhtml/Writer2xhtml.java
new file mode 100644
index 0000000..7467b29
--- /dev/null
+++ b/source/java/org/openoffice/da/comp/writer2xhtml/Writer2xhtml.java
@@ -0,0 +1,358 @@
+/************************************************************************
+ *
+ * Writer2xhtml.java
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * Copyright: 2002-2014 by Henrik Just
+ *
+ * All Rights Reserved.
+ *
+ * Version 1.6 (2014-10-09)
+ *
+ */
+
+package org.openoffice.da.comp.writer2xhtml;
+
+// TODO: Create common base for dispatcher classes
+
+import java.awt.Desktop;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import com.sun.star.beans.PropertyValue;
+import com.sun.star.beans.XPropertyAccess;
+import com.sun.star.frame.XController;
+import com.sun.star.frame.XFrame;
+import com.sun.star.frame.XModel;
+import com.sun.star.frame.XStorable;
+import com.sun.star.io.XInputStream;
+import com.sun.star.lib.uno.helper.WeakBase;
+import com.sun.star.task.XStatusIndicator;
+import com.sun.star.task.XStatusIndicatorFactory;
+import com.sun.star.ucb.XSimpleFileAccess2;
+import com.sun.star.ui.dialogs.ExecutableDialogResults;
+import com.sun.star.ui.dialogs.XExecutableDialog;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.util.XModifiable;
+
+import org.openoffice.da.comp.w2lcommon.filter.UNOConverter;
+import org.openoffice.da.comp.w2lcommon.helper.MessageBox;
+
+import writer2latex.util.Misc;
+
+/** This class implements the ui (dispatch) commands provided by Writer2xhtml.
+ */
+public final class Writer2xhtml extends WeakBase
+ implements com.sun.star.lang.XServiceInfo,
+ com.sun.star.frame.XDispatchProvider,
+ com.sun.star.lang.XInitialization,
+ com.sun.star.frame.XDispatch {
+
+ private static final String PROTOCOL = "org.openoffice.da.writer2xhtml:";
+
+ private enum TargetFormat { xhtml, xhtml11, xhtml_mathml, html5, epub };
+
+ // From constructor+initialization
+ private final XComponentContext m_xContext;
+ private XFrame m_xFrame;
+ private XModel xModel = null;
+
+ // Global data
+ private PropertyValue[] mediaProps = null;
+
+ public static final String __implementationName = Writer2xhtml.class.getName();
+ public static final String __serviceName = "com.sun.star.frame.ProtocolHandler";
+ private static final String[] m_serviceNames = { __serviceName };
+
+ // TODO: These should be configurable
+ private TargetFormat xhtmlFormat = TargetFormat.xhtml_mathml;
+ private TargetFormat epubFormat = TargetFormat.epub;
+
+ private String getTargetExtension(TargetFormat format) {
+ switch (format) {
+ case xhtml: return ".html";
+ case xhtml11: return ".xhtml";
+ case xhtml_mathml: return ".xhtml";
+ case html5: return ".html";
+ case epub: return ".epub";
+ default: return "";
+ }
+ }
+
+ private String getDialogName(TargetFormat format) {
+ switch (format) {
+ case xhtml: return "org.openoffice.da.comp.writer2xhtml.XhtmlOptionsDialog";
+ case xhtml11: return "org.openoffice.da.comp.writer2xhtml.XhtmlOptionsDialog";
+ case xhtml_mathml: return "org.openoffice.da.comp.writer2xhtml.XhtmlOptionsDialogMath";
+ case html5: return "org.openoffice.da.comp.writer2xhtml.XhtmlOptionsDialogMath";
+ case epub: return "org.openoffice.da.comp.writer2xhtml.EpubOptionsDialog";
+ default: return "";
+ }
+ }
+
+ private String getFilterName(TargetFormat format) {
+ switch (format) {
+ case xhtml: return "org.openoffice.da.writer2xhtml";
+ case xhtml11: return "org.openoffice.da.writer2xhtml11";
+ case xhtml_mathml: return "org.openoffice.da.writer2xhtml.mathml";
+ case html5: return "org.openoffice.da.writer2xhtml5";
+ case epub: return "org.openoffice.da.writer2xhtml.epub";
+ default: return "";
+ }
+ }
+
+ public Writer2xhtml(XComponentContext xContext) {
+ m_xContext = xContext;
+ }
+
+ // com.sun.star.lang.XInitialization:
+ public void initialize( Object[] object )
+ throws com.sun.star.uno.Exception {
+ if ( object.length > 0 ) {
+ // The first item is the current frame
+ m_xFrame = (com.sun.star.frame.XFrame) UnoRuntime.queryInterface(
+ com.sun.star.frame.XFrame.class, object[0]);
+ // Get the model for the document from the frame
+ XController xController = m_xFrame.getController();
+ if (xController!=null) {
+ xModel = xController.getModel();
+ }
+ }
+ }
+
+ // com.sun.star.lang.XServiceInfo:
+ public String getImplementationName() {
+ return __implementationName;
+ }
+
+ public boolean supportsService( String sService ) {
+ int len = m_serviceNames.length;
+
+ for( int i=0; i < len; i++) {
+ if (sService.equals(m_serviceNames[i]))
+ return true;
+ }
+ return false;
+ }
+
+ public String[] getSupportedServiceNames() {
+ return m_serviceNames;
+ }
+
+
+ // com.sun.star.frame.XDispatchProvider:
+ public com.sun.star.frame.XDispatch queryDispatch( com.sun.star.util.URL aURL,
+ String sTargetFrameName, int iSearchFlags ) {
+ if ( aURL.Protocol.compareTo(PROTOCOL) == 0 ) {
+ if ( aURL.Path.compareTo("PublishAsXHTML") == 0 )
+ return this;
+ else if ( aURL.Path.compareTo("PublishAsEPUB") == 0 )
+ return this;
+ }
+ return null;
+ }
+
+ public com.sun.star.frame.XDispatch[] queryDispatches(
+ com.sun.star.frame.DispatchDescriptor[] seqDescriptors ) {
+ int nCount = seqDescriptors.length;
+ com.sun.star.frame.XDispatch[] seqDispatcher =
+ new com.sun.star.frame.XDispatch[seqDescriptors.length];
+
+ for( int i=0; i < nCount; ++i ) {
+ seqDispatcher[i] = queryDispatch(seqDescriptors[i].FeatureURL,
+ seqDescriptors[i].FrameName,
+ seqDescriptors[i].SearchFlags );
+ }
+ return seqDispatcher;
+ }
+
+
+ // com.sun.star.frame.XDispatch:
+ public void dispatch( com.sun.star.util.URL aURL,
+ com.sun.star.beans.PropertyValue[] aArguments ) {
+ if ( aURL.Protocol.compareTo(PROTOCOL) == 0 ) {
+ System.out.println(aURL.Protocol+" "+aURL.Path);
+ if ( aURL.Path.compareTo("PublishAsXHTML") == 0 ) {
+ publish(xhtmlFormat);
+ return;
+ }
+ else if ( aURL.Path.compareTo("PublishAsEPUB") == 0 ) {
+ publish(epubFormat);
+ return;
+ }
+ }
+ }
+
+ public void addStatusListener( com.sun.star.frame.XStatusListener xControl,
+ com.sun.star.util.URL aURL ) {
+ }
+
+ public void removeStatusListener( com.sun.star.frame.XStatusListener xControl,
+ com.sun.star.util.URL aURL ) {
+ }
+
+ // The actual commands...
+
+ private void publish(TargetFormat format) {
+ if (saveDocument() && updateMediaProperties(xhtmlFormat)) {
+ // Create a (somewhat coarse grained) status indicator/progress bar
+ XStatusIndicatorFactory xFactory = (com.sun.star.task.XStatusIndicatorFactory)
+ UnoRuntime.queryInterface(com.sun.star.task.XStatusIndicatorFactory.class, m_xFrame);
+ XStatusIndicator xStatus = xFactory.createStatusIndicator();
+ xStatus.start("Writer2xhtml",10);
+ xStatus.setValue(1); // At least we have started, that's 10% :-)
+
+ System.out.println("Document location "+xModel.getURL());
+
+ try {
+ // Convert to desired format
+ UNOConverter converter = new UNOConverter(mediaProps, m_xContext);
+ // Initialize the file access (to read the office document)
+ XSimpleFileAccess2 sfa2 = null;
+ try {
+ Object sfaObject = m_xContext.getServiceManager().createInstanceWithContext(
+ "com.sun.star.ucb.SimpleFileAccess", m_xContext);
+ sfa2 = (XSimpleFileAccess2) UnoRuntime.queryInterface(XSimpleFileAccess2.class, sfaObject);
+ }
+ catch (com.sun.star.uno.Exception e) {
+ // failed to get SimpleFileAccess service (should not happen)
+ }
+ XInputStream xis = sfa2.openFileRead(xModel.getURL());
+ converter.convert(xis);
+ xis.closeInput();
+ }
+ catch (IOException | com.sun.star.uno.Exception e) {
+ xStatus.end();
+ MessageBox msgBox = new MessageBox(m_xContext, m_xFrame);
+ msgBox.showMessage("Writer2xhtml Error","Failed to export document");
+ return;
+ }
+ xStatus.setValue(6); // Export is finished, that's more than half :-)
+
+ if (xModel.getURL().startsWith("file:")) {
+ File file = urlToFile(getTargetURL(format));
+ if (file.exists()) {
+ // Open the file in the default application on this system (if any)
+ if (Desktop.isDesktopSupported()) {
+ Desktop desktop = Desktop.getDesktop();
+ try {
+ desktop.open(file);
+ } catch (IOException e) {
+ System.err.println(e.getMessage());
+ }
+ }
+ }
+ else {
+ MessageBox msgBox = new MessageBox(m_xContext, m_xFrame);
+ msgBox.showMessage("Writer2xhtml Error","Failed to open exported document");
+ }
+ }
+ else {
+ MessageBox msgBox = new MessageBox(m_xContext, m_xFrame);
+ msgBox.showMessage("Writer2xhtml Error","Cannot open document on the location "+getTargetURL(format));
+ }
+
+ xStatus.setValue(10); // The user will usually not see this...
+
+ xStatus.end();
+ }
+ }
+
+ private boolean saveDocument() {
+ String sDocumentUrl = xModel.getURL();
+ if (sDocumentUrl.length()!=0) { // The document has a location
+ XModifiable xModifiable = (XModifiable) UnoRuntime.queryInterface(XModifiable.class, xModel);
+ if (xModifiable.isModified()) { // It is modified and need to be saved
+ XStorable xStorable = (XStorable) UnoRuntime.queryInterface(XStorable.class, xModel);
+ try {
+ xStorable.store();
+ } catch (com.sun.star.io.IOException e) {
+ return false;
+ }
+ }
+ }
+ else { // No location, ask the user to save the document
+ MessageBox msgBox = new MessageBox(m_xContext, m_xFrame);
+ msgBox.showMessage("Document not saved!","Please save the document before publishing the file");
+ return false;
+ }
+ return true;
+ }
+
+ // Some utility methods
+ private String getTargetURL(TargetFormat format) {
+ return Misc.removeExtension(xModel.getURL())+getTargetExtension(format);
+ }
+
+ private void prepareMediaProperties(TargetFormat format) {
+ // Create inital media properties
+ mediaProps = new PropertyValue[2];
+ mediaProps[0] = new PropertyValue();
+ mediaProps[0].Name = "FilterName";
+ mediaProps[0].Value = getFilterName(format);
+ mediaProps[1] = new PropertyValue();
+ mediaProps[1].Name = "URL";
+ mediaProps[1].Value = getTargetURL(format);
+ }
+
+ private boolean updateMediaProperties(TargetFormat format) {
+ prepareMediaProperties(format);
+
+ try {
+ // Display options dialog
+ Object dialog = m_xContext.getServiceManager()
+ .createInstanceWithContext(getDialogName(format), m_xContext);
+
+ XPropertyAccess xPropertyAccess = (XPropertyAccess)
+ UnoRuntime.queryInterface(XPropertyAccess.class, dialog);
+ xPropertyAccess.setPropertyValues(mediaProps);
+
+ XExecutableDialog xDialog = (XExecutableDialog)
+ UnoRuntime.queryInterface(XExecutableDialog.class, dialog);
+ if (xDialog.execute()==ExecutableDialogResults.OK) {
+ mediaProps = xPropertyAccess.getPropertyValues();
+ return true;
+ }
+ else {
+ mediaProps = null;
+ return false;
+ }
+ }
+ catch (com.sun.star.beans.UnknownPropertyException e) {
+ // setPropertyValues will not fail..
+ mediaProps = null;
+ return false;
+ }
+ catch (com.sun.star.uno.Exception e) {
+ // getServiceManager will not fail..
+ mediaProps = null;
+ return false;
+ }
+ }
+
+ private File urlToFile(String sUrl) {
+ try {
+ return new File(new URI(sUrl));
+ }
+ catch (URISyntaxException e) {
+ return new File(".");
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/source/java/writer2latex/util/Misc.java b/source/java/writer2latex/util/Misc.java
index 6417dfe..a45f6b4 100644
--- a/source/java/writer2latex/util/Misc.java
+++ b/source/java/writer2latex/util/Misc.java
@@ -20,7 +20,7 @@
*
* All Rights Reserved.
*
- * Version 1.4 (2014-09-16)
+ * Version 1.4 (2014-10-10)
*
*/
@@ -329,10 +329,9 @@ public class Misc{
}
}
- public static final String removeExtension(String sName) {
- int n = sName.lastIndexOf(".");
- if (n<0) { return sName; }
- return sName.substring(0,n);
+ public static final String removeExtension(String sURL) {
+ String sExt = getFileExtension(sURL);
+ return sURL.substring(0, sURL.length()-sExt.length());
}
/*
diff --git a/source/oxt/writer2xhtml/Addons.xcu b/source/oxt/writer2xhtml/Addons.xcu
new file mode 100644
index 0000000..41bfb93
--- /dev/null
+++ b/source/oxt/writer2xhtml/Addons.xcu
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+ com.sun.star.text.TextDocument
+
+
+ Publish as EPUB
+ Publicer som EPUB
+
+
+ _self
+
+
+ org.openoffice.da.writer2xhtml:PublishAsEPUB
+
+
+ %origin%/icons/epub
+
+
+
+
+ com.sun.star.text.TextDocument
+
+
+ Publish as XHTML
+ Publicer som XHTML
+
+
+ _self
+
+
+ org.openoffice.da.writer2xhtml:PublishAsXHTML
+
+
+ %origin%/icons/html5
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/source/oxt/writer2xhtml/META-INF/manifest.xml b/source/oxt/writer2xhtml/META-INF/manifest.xml
index aedff71..7bd4478 100644
--- a/source/oxt/writer2xhtml/META-INF/manifest.xml
+++ b/source/oxt/writer2xhtml/META-INF/manifest.xml
@@ -1,6 +1,18 @@
+
+
+
+
+
+
diff --git a/source/oxt/writer2xhtml/Office/UI/WriterWindowState.xcu b/source/oxt/writer2xhtml/Office/UI/WriterWindowState.xcu
new file mode 100644
index 0000000..676fa85
--- /dev/null
+++ b/source/oxt/writer2xhtml/Office/UI/WriterWindowState.xcu
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+ Writer2xhtml
+
+
+
+
+
\ No newline at end of file
diff --git a/source/oxt/writer2xhtml/ProtocolHandler.xcu b/source/oxt/writer2xhtml/ProtocolHandler.xcu
new file mode 100644
index 0000000..8a1ee4b
--- /dev/null
+++ b/source/oxt/writer2xhtml/ProtocolHandler.xcu
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+ org.openoffice.da.writer2xhtml:*
+
+
+
+
\ No newline at end of file
diff --git a/source/oxt/writer2xhtml/icons/epub_16.bmp b/source/oxt/writer2xhtml/icons/epub_16.bmp
new file mode 100644
index 0000000..0446323
Binary files /dev/null and b/source/oxt/writer2xhtml/icons/epub_16.bmp differ
diff --git a/source/oxt/writer2xhtml/icons/epub_16h.bmp b/source/oxt/writer2xhtml/icons/epub_16h.bmp
new file mode 100644
index 0000000..da608c3
Binary files /dev/null and b/source/oxt/writer2xhtml/icons/epub_16h.bmp differ
diff --git a/source/oxt/writer2xhtml/icons/epub_26.bmp b/source/oxt/writer2xhtml/icons/epub_26.bmp
new file mode 100644
index 0000000..06f1ffa
Binary files /dev/null and b/source/oxt/writer2xhtml/icons/epub_26.bmp differ
diff --git a/source/oxt/writer2xhtml/icons/epub_26h.bmp b/source/oxt/writer2xhtml/icons/epub_26h.bmp
new file mode 100644
index 0000000..fe561d6
Binary files /dev/null and b/source/oxt/writer2xhtml/icons/epub_26h.bmp differ
diff --git a/source/oxt/writer2xhtml/icons/html5_16.bmp b/source/oxt/writer2xhtml/icons/html5_16.bmp
new file mode 100644
index 0000000..ad2b2f6
Binary files /dev/null and b/source/oxt/writer2xhtml/icons/html5_16.bmp differ
diff --git a/source/oxt/writer2xhtml/icons/html5_16h.bmp b/source/oxt/writer2xhtml/icons/html5_16h.bmp
new file mode 100644
index 0000000..04491b2
Binary files /dev/null and b/source/oxt/writer2xhtml/icons/html5_16h.bmp differ
diff --git a/source/oxt/writer2xhtml/icons/html5_26.bmp b/source/oxt/writer2xhtml/icons/html5_26.bmp
new file mode 100644
index 0000000..0ab5dc1
Binary files /dev/null and b/source/oxt/writer2xhtml/icons/html5_26.bmp differ
diff --git a/source/oxt/writer2xhtml/icons/html5_26h.bmp b/source/oxt/writer2xhtml/icons/html5_26h.bmp
new file mode 100644
index 0000000..1a93e05
Binary files /dev/null and b/source/oxt/writer2xhtml/icons/html5_26h.bmp differ