First draft of w2l toolbar

git-svn-id: svn://svn.code.sf.net/p/writer2latex/code/trunk@184 f0f2a975-2e09-46c8-9428-3b39399b9f3c
This commit is contained in:
henrikjust 2014-10-10 13:51:02 +00:00
parent 25bc476ffa
commit a50dad69f4
20 changed files with 738 additions and 337 deletions

View file

@ -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<OutputFile> 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 );
}
}

View file

@ -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 <code>XInputStream</code> 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<String,String> filterNames = new HashMap<String,String>();
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<OutputFile> 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;
}
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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,

View file

@ -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(".");
}
}
}