Started modifying project structure

This commit is contained in:
Georgy Litvinov 2020-12-13 14:03:25 +01:00
parent 4e16ed01c2
commit 1e4ee37f89
566 changed files with 3340 additions and 176 deletions

View file

@ -0,0 +1,175 @@
/*************************************************************************
*
* The Contents of this file are made available subject to the terms of
* either of the GNU Lesser General Public License Version 2.1
*
* Sun Microsystems Inc., October, 2000
*
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2000 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* 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
*
* The Initial Developer of the Original Code is: Sun Microsystems, Inc..
*
* Copyright: 2002 by Sun Microsystems, Inc.
*
* All Rights Reserved.
*
* Contributor(s): Cedric Bosdonnat
*
*
************************************************************************/
package org.libreoffice.example.comp;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.lang.reflect.Method;
import java.util.ArrayList;
import com.sun.star.lang.XSingleComponentFactory;
import com.sun.star.registry.XRegistryKey;
/**
* Component main registration class.
*
* <p><strong>This class should not be modified.</strong></p>
*
* @author Cedric Bosdonnat aka. cedricbosdo
*
*/
public class RegistrationHandler {
/**
* Get a component factory for the implementations handled by this class.
*
* <p>This method calls all the methods of the same name from the classes listed
* in the <code>RegistrationHandler.classes</code> file. <strong>This method
* should not be modified.</strong></p>
*
* @param pImplementationName the name of the implementation to create.
*
* @return the factory which can create the implementation.
*/
public static XSingleComponentFactory __getComponentFactory(String sImplementationName ) {
XSingleComponentFactory xFactory = null;
Class[] classes = findServicesImplementationClasses();
int i = 0;
while (i < classes.length && xFactory == null) {
Class clazz = classes[i];
if ( sImplementationName.equals( clazz.getCanonicalName() ) ) {
try {
Class[] getTypes = new Class[]{String.class};
Method getFactoryMethod = clazz.getMethod("__getComponentFactory", getTypes);
Object o = getFactoryMethod.invoke(null, sImplementationName);
xFactory = (XSingleComponentFactory)o;
} catch (Exception e) {
// Nothing to do: skip
System.err.println("Error happened");
e.printStackTrace();
}
}
i++;
}
return xFactory;
}
/**
* Writes the services implementation informations to the UNO registry.
*
* <p>This method calls all the methods of the same name from the classes listed
* in the <code>RegistrationHandler.classes</code> file. <strong>This method
* should not be modified.</strong></p>
*
* @param pRegistryKey the root registry key where to write the informations.
*
* @return <code>true</code> if the informations have been successfully written
* to the registry key, <code>false</code> otherwise.
*/
public static boolean __writeRegistryServiceInfo(XRegistryKey xRegistryKey ) {
Class[] classes = findServicesImplementationClasses();
boolean success = true;
int i = 0;
while (i < classes.length && success) {
Class clazz = classes[i];
try {
Class[] writeTypes = new Class[]{XRegistryKey.class};
Method getFactoryMethod = clazz.getMethod("__writeRegistryServiceInfo", writeTypes);
Object o = getFactoryMethod.invoke(null, xRegistryKey);
success = success && ((Boolean)o).booleanValue();
} catch (Exception e) {
success = false;
e.printStackTrace();
}
i++;
}
return success;
}
/**
* @return all the UNO implementation classes.
*/
private static Class[] findServicesImplementationClasses() {
ArrayList<Class> classes = new ArrayList<Class>();
InputStream in = RegistrationHandler.class.getResourceAsStream("RegistrationHandler.classes");
LineNumberReader reader = new LineNumberReader(new InputStreamReader(in));
try {
String line = reader.readLine();
while (line != null) {
if (!line.equals("")) {
line = line.trim();
try {
Class clazz = Class.forName(line);
Class[] writeTypes = new Class[]{XRegistryKey.class};
Class[] getTypes = new Class[]{String.class};
Method writeRegMethod = clazz.getMethod("__writeRegistryServiceInfo", writeTypes);
Method getFactoryMethod = clazz.getMethod("__getComponentFactory", getTypes);
if (writeRegMethod != null && getFactoryMethod != null) {
classes.add(clazz);
}
} catch (Exception e) {
e.printStackTrace();
}
}
line = reader.readLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
reader.close();
in.close();
} catch (Exception e) {};
}
return classes.toArray(new Class[classes.size()]);
}
}

View file

@ -0,0 +1,13 @@
package org.libreoffice.example.comp.tests;
import org.junit.runner.RunWith;
import org.junit.runners.Suite.SuiteClasses;
import org.libreoffice.example.comp.tests.base.UnoSuite;
import org.libreoffice.example.comp.tests.uno.WriterTest;
@RunWith(UnoSuite.class)
@SuiteClasses({WriterTest.class})
public class UnoTests {
}

View file

@ -0,0 +1,75 @@
package org.libreoffice.example.comp.tests.base;
import java.util.List;
import org.junit.runner.Runner;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.Suite;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.RunnerBuilder;
import com.sun.star.frame.XDesktop;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
public class UnoSuite extends Suite {
private static XComponentContext componentContext;
public UnoSuite(Class<?> klass, RunnerBuilder builder) throws InitializationError {
super(klass, builder);
}
public UnoSuite(RunnerBuilder builder, Class<?>[] classes) throws InitializationError {
super(builder, classes);
}
public UnoSuite(Class<?> klass, Class<?>[] suiteClasses) throws InitializationError {
super(klass, suiteClasses);
}
public UnoSuite(Class<?> klass, List<Runner> runners) throws InitializationError {
super(klass, runners);
}
public UnoSuite(RunnerBuilder builder, Class<?> klass, Class<?>[] suiteClasses) throws InitializationError {
super(builder, klass, suiteClasses);
}
@Override
public void run(RunNotifier arg0) {
try {
startOffice();
} catch (Exception e) {
e.printStackTrace();
}
super.run(arg0);
stopOffice();
}
private void startOffice() throws Exception {
componentContext = com.sun.star.comp.helper.Bootstrap.bootstrap();
}
private void stopOffice() {
try {
if (componentContext != null) {
// Only the uno test suite which started the office can stop it
XMultiComponentFactory xMngr = componentContext.getServiceManager();
Object oDesktop = xMngr.createInstanceWithContext("com.sun.star.frame.Desktop", componentContext);
XDesktop xDesktop = (XDesktop)UnoRuntime.queryInterface(XDesktop.class, oDesktop);
xDesktop.terminate();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static XComponentContext getComponentContext() {
return componentContext;
}
}

View file

@ -0,0 +1,28 @@
package org.libreoffice.example.comp.tests.helper;
import com.sun.star.beans.PropertyValue;
import com.sun.star.frame.FrameSearchFlag;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.text.XTextDocument;
import com.sun.star.uno.Exception;
import com.sun.star.uno.UnoRuntime;
import org.libreoffice.example.comp.tests.base.UnoSuite;
public class UnoHelper {
public static XTextDocument getWriterDocument() throws Exception {
XMultiComponentFactory xMngr = UnoSuite.getComponentContext().getServiceManager();
Object oDesktop = xMngr.createInstanceWithContext("com.sun.star.frame.Desktop", UnoSuite.getComponentContext());
XComponentLoader xLoader = (XComponentLoader)UnoRuntime.queryInterface(
XComponentLoader.class, oDesktop);
XComponent xDoc = xLoader.loadComponentFromURL("private:factory/swriter", "_default",
FrameSearchFlag.ALL, new PropertyValue[0]);
return (XTextDocument)UnoRuntime.queryInterface(XTextDocument.class, xDoc);
}
}

View file

@ -0,0 +1,26 @@
package org.libreoffice.example.comp.tests.uno;
import static org.junit.Assert.assertNotNull;
import org.junit.Before;
import org.junit.Test;
import com.sun.star.text.XTextDocument;
import org.libreoffice.example.comp.tests.helper.UnoHelper;
public class WriterTest {
private XTextDocument xTextDocument;
@Before
public void setUp() throws Exception {
xTextDocument = UnoHelper.getWriterDocument();
}
@Test
public void test() {
assertNotNull(xTextDocument);
}
}

View file

@ -0,0 +1,187 @@
/************************************************************************
*
* ByteArrayXStream.java
*
* Copyright: 2002-2008 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.0 (2008-07-22)
*
*/
package org.openoffice.da.comp.w2lcommon.filter;
// This class is based on these java uno adapter classes:
// com.sun.star.lib.uno.adapter.ByteArrayToXInputStreamAdapter;
// com.sun.star.lib.uno.adapter.XOutputStreamToByteArrayAdapter;
// See http://go-oo.org/lxr/source/udk/javaunohelper/com/sun/star/lib/uno/adapter/XOutputStreamToByteArrayAdapter.java
// and http://go-oo.org/lxr/source/udk/javaunohelper/com/sun/star/lib/uno/adapter/ByteArrayToXInputStreamAdapter.java
// for original source
import com.sun.star.io.XInputStream;
import com.sun.star.io.XOutputStream;
import com.sun.star.io.XSeekable;
import com.sun.star.io.XStream;
/** <p>This is a java-uno adapter class which implements XStream using a
* byte array. (We need this because XGraphicProvider demans read/write access
* when storing a graphic to a stream.)</p>
*/
public class ByteArrayXStream implements XInputStream, XOutputStream, XSeekable, XStream {
// Keep data about our byte array (we read and write to the same byte array)
private int initialSize = 100240; // 10 kb
private int size = 0; // The current buffer size
private int position = 0; // The current write position, always<=size
private int readPosition = 0; // The current read position, always<=position
private boolean closed = false; // The XStream is closed
private byte[] buffer; // The buffer
// Constructor: Initialize the byte array
public ByteArrayXStream() {
size = initialSize;
buffer = new byte[size];
}
// Implementation of XOutputStream
public void closeOutput()
throws com.sun.star.io.NotConnectedException,
com.sun.star.io.BufferSizeExceededException,
com.sun.star.io.IOException {
// trim buffer
if ( buffer.length > position) {
byte[] newBuffer = new byte[position];
System.arraycopy(buffer, 0, newBuffer, 0, position);
buffer = newBuffer;
}
closed = true;
}
public void flush()
throws com.sun.star.io.NotConnectedException,
com.sun.star.io.BufferSizeExceededException,
com.sun.star.io.IOException {
}
public void writeBytes(byte[] values)
throws com.sun.star.io.NotConnectedException,
com.sun.star.io.BufferSizeExceededException,
com.sun.star.io.IOException {
if ( values.length > size-position ) {
byte[] newBuffer = null;
while ( values.length > size-position )
size *= 2;
newBuffer = new byte[size];
System.arraycopy(buffer, 0, newBuffer, 0, position);
buffer = newBuffer;
}
System.arraycopy(values, 0, buffer, position, values.length);
position += values.length;
}
// Implementation of XInputStream
private void _check() throws com.sun.star.io.NotConnectedException, com.sun.star.io.IOException {
if(closed) {
throw new com.sun.star.io.IOException("input closed");
}
}
public int available() throws com.sun.star.io.NotConnectedException, com.sun.star.io.IOException {
_check();
return position - readPosition;
}
public void closeInput() throws com.sun.star.io.NotConnectedException, com.sun.star.io.IOException {
closed = true;
}
public int readBytes(byte[][] values, int param) throws com.sun.star.io.NotConnectedException, com.sun.star.io.BufferSizeExceededException, com.sun.star.io.IOException {
_check();
try {
int remain = (int)(position - readPosition);
if (param > remain) param = remain;
/* ARGH!!! */
if (values[0] == null){
values[0] = new byte[param];
// System.err.println("allocated new buffer of "+param+" bytes");
}
System.arraycopy(buffer, readPosition, values[0], 0, param);
// System.err.println("readbytes() -> "+param);
readPosition += param;
return param;
} catch (ArrayIndexOutOfBoundsException ae) {
// System.err.println("readbytes() -> ArrayIndexOutOfBounds");
ae.printStackTrace();
throw new com.sun.star.io.BufferSizeExceededException("buffer overflow");
} catch (Exception e) {
// System.err.println("readbytes() -> Exception: "+e.getMessage());
e.printStackTrace();
throw new com.sun.star.io.IOException("error accessing buffer");
}
}
public int readSomeBytes(byte[][] values, int param) throws com.sun.star.io.NotConnectedException, com.sun.star.io.BufferSizeExceededException, com.sun.star.io.IOException {
// System.err.println("readSomebytes()");
return readBytes(values, param);
}
public void skipBytes(int param) throws com.sun.star.io.NotConnectedException, com.sun.star.io.BufferSizeExceededException, com.sun.star.io.IOException {
// System.err.println("skipBytes("+param+")");
_check();
if (param > (position - readPosition))
throw new com.sun.star.io.BufferSizeExceededException("buffer overflow");
readPosition += param;
}
// Implementation of XSeekable
public long getLength() throws com.sun.star.io.IOException {
// System.err.println("getLength() -> "+m_length);
if (buffer != null) return position;
else throw new com.sun.star.io.IOException("no bytes");
}
public long getPosition() throws com.sun.star.io.IOException {
// System.err.println("getPosition() -> "+m_pos);
if (buffer != null) return readPosition;
else throw new com.sun.star.io.IOException("no bytes");
}
public void seek(long param) throws com.sun.star.lang.IllegalArgumentException, com.sun.star.io.IOException {
// System.err.println("seek("+param+")");
if (buffer != null) {
if (param < 0 || param > position) throw new com.sun.star.lang.IllegalArgumentException("invalid seek position");
else readPosition = (int)param;
} else throw new com.sun.star.io.IOException("no bytes");
}
// Implementation of XStream
public XInputStream getInputStream() { return this; }
public XOutputStream getOutputStream() { return this; }
// Get the buffer
public byte[] getBuffer() { return buffer; }
}

View file

@ -0,0 +1,870 @@
/************************************************************************
*
* ConfigurationDialogBase.java
*
* Copyright: 2002-2015 by Henrik Just
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-04-09)
*
*/
package org.openoffice.da.comp.w2lcommon.filter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import com.sun.star.awt.XContainerWindowEventHandler;
import com.sun.star.awt.XDialog;
import com.sun.star.awt.XDialogProvider2;
import com.sun.star.awt.XWindow;
import com.sun.star.container.NoSuchElementException;
import com.sun.star.io.NotConnectedException;
import com.sun.star.io.XInputStream;
import com.sun.star.io.XOutputStream;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.ucb.CommandAbortedException;
import com.sun.star.ucb.XSimpleFileAccess2;
import com.sun.star.ui.dialogs.ExecutableDialogResults;
import com.sun.star.uno.AnyConverter;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.util.XStringSubstitution;
import com.sun.star.lib.uno.helper.WeakBase;
import com.sun.star.lib.uno.adapter.XInputStreamToInputStreamAdapter;
import com.sun.star.lib.uno.adapter.XOutputStreamToOutputStreamAdapter;
import writer2latex.api.ComplexOption;
import writer2latex.api.Config;
import writer2latex.api.ConverterFactory;
import writer2latex.util.Misc;
import org.openoffice.da.comp.w2lcommon.helper.DialogAccess;
import org.openoffice.da.comp.w2lcommon.helper.FilePicker;
import org.openoffice.da.comp.w2lcommon.helper.StyleNameProvider;
/** This is a base implementation of a uno component which supports several option pages
* with a single <code>XContainerWindowEventHandler</code>. The title of the dialogs
* are used to differentiate between the individual pages
*/
public abstract class ConfigurationDialogBase extends WeakBase implements XContainerWindowEventHandler {
// The full path to the configuration file we handle
private String sConfigFileName = null;
// The component context
protected XComponentContext xContext;
// File picker wrapper
protected FilePicker filePicker = null;
// UNO simple file access service
protected XSimpleFileAccess2 sfa2 = null;
// UNO path substitution
protected XStringSubstitution xPathSub = null;
// The configuration implementation
protected Config config;
// The individual page handlers (the subclass must populate this)
protected Map<String,PageHandler> pageHandlers = new HashMap<String,PageHandler>();
// The subclass must provide these:
// MIME type of the document type we configure
protected abstract String getMIMEType();
// The dialog library containing the "new" and "delete" dialogs
protected abstract String getDialogLibraryName();
// The file name used for persistent storage of the edited configuration
protected abstract String getConfigFileName();
/** Create a new <code>ConfigurationDialogBase</code> */
public ConfigurationDialogBase(XComponentContext xContext) {
this.xContext = xContext;
// Get the file picker
filePicker = new FilePicker(xContext);
// Get the SimpleFileAccess service
try {
Object sfaObject = xContext.getServiceManager().createInstanceWithContext(
"com.sun.star.ucb.SimpleFileAccess", xContext);
sfa2 = (XSimpleFileAccess2) UnoRuntime.queryInterface(XSimpleFileAccess2.class, sfaObject);
}
catch (com.sun.star.uno.Exception e) {
// failed to get SimpleFileAccess service (should not happen)
}
// Create the config file name
try {
Object psObject = xContext.getServiceManager().createInstanceWithContext(
"com.sun.star.util.PathSubstitution", xContext);
xPathSub = (XStringSubstitution) UnoRuntime.queryInterface(XStringSubstitution.class, psObject);
sConfigFileName = xPathSub.substituteVariables("$(user)/"+getConfigFileName(), false);
}
catch (com.sun.star.uno.Exception e) {
// failed to get PathSubstitution service (should not happen)
}
// Create the configuration
config = ConverterFactory.createConverter(getMIMEType()).getConfig();
}
// Implement XContainerWindowEventHandler
public boolean callHandlerMethod(XWindow xWindow, Object event, String sMethod)
throws com.sun.star.lang.WrappedTargetException {
XDialog xDialog = (XDialog)UnoRuntime.queryInterface(XDialog.class, xWindow);
String sTitle = xDialog.getTitle();
if (!pageHandlers.containsKey(sTitle)) {
throw new com.sun.star.lang.WrappedTargetException("Unknown dialog "+sTitle);
}
DialogAccess dlg = new DialogAccess(xDialog);
try {
if (sMethod.equals("external_event") ) {
return handleExternalEvent(dlg, sTitle, event);
}
}
catch (com.sun.star.uno.RuntimeException e) {
throw e;
}
catch (com.sun.star.uno.Exception e) {
throw new com.sun.star.lang.WrappedTargetException(sMethod, this, e);
}
return pageHandlers.get(sTitle).handleEvent(dlg, sMethod);
}
private boolean handleExternalEvent(DialogAccess dlg, String sTitle, Object aEventObject) throws com.sun.star.uno.Exception {
try {
String sMethod = AnyConverter.toString(aEventObject);
if (sMethod.equals("ok")) {
loadConfig(); // The file may have been changed by other pages, thus we reload
pageHandlers.get(sTitle).getControls(dlg);
saveConfig();
return true;
}
else if (sMethod.equals("back") || sMethod.equals("initialize")) {
loadConfig();
pageHandlers.get(sTitle).setControls(dlg);
return true;
}
}
catch (com.sun.star.lang.IllegalArgumentException e) {
throw new com.sun.star.lang.IllegalArgumentException(
"Method external_event requires a string in the event object argument.", this,(short) -1);
}
return false;
}
// Load the user configuration from file
private void loadConfig() {
if (sfa2!=null && sConfigFileName!=null) {
try {
XInputStream xIs = sfa2.openFileRead(sConfigFileName);
if (xIs!=null) {
InputStream is = new XInputStreamToInputStreamAdapter(xIs);
config.read(is);
is.close();
xIs.closeInput();
}
}
catch (IOException e) {
// ignore
}
catch (NotConnectedException e) {
// ignore
}
catch (CommandAbortedException e) {
// ignore
}
catch (com.sun.star.uno.Exception e) {
// ignore
}
}
}
// Save the user configuration
private void saveConfig() {
if (sfa2!=null && sConfigFileName!=null) {
try {
//Remove the file if it exists
if (sfa2.exists(sConfigFileName)) {
sfa2.kill(sConfigFileName);
}
// Then write the new contents
XOutputStream xOs = sfa2.openFileWrite(sConfigFileName);
if (xOs!=null) {
OutputStream os = new XOutputStreamToOutputStreamAdapter(xOs);
config.write(os);
os.close();
xOs.closeOutput();
}
}
catch (IOException e) {
// ignore
}
catch (NotConnectedException e) {
// ignore
}
catch (CommandAbortedException e) {
// ignore
}
catch (com.sun.star.uno.Exception e) {
// ignore
}
}
}
// Inner class to handle the individual option pages
protected abstract class PageHandler {
protected abstract void getControls(DialogAccess dlg);
protected abstract void setControls(DialogAccess dlg);
protected abstract boolean handleEvent(DialogAccess dlg, String sMethodName);
// Methods to set and get controls based on config
protected void checkBoxFromConfig(DialogAccess dlg, String sCheckBoxName, String sConfigName) {
dlg.setCheckBoxStateAsBoolean(sCheckBoxName, "true".equals(config.getOption(sConfigName)));
}
protected void checkBoxToConfig(DialogAccess dlg, String sCheckBoxName, String sConfigName) {
config.setOption(sConfigName, Boolean.toString(dlg.getCheckBoxStateAsBoolean(sCheckBoxName)));
}
protected void textFieldFromConfig(DialogAccess dlg, String sTextBoxName, String sConfigName) {
dlg.setTextFieldText(sTextBoxName, config.getOption(sConfigName));
}
protected void textFieldToConfig(DialogAccess dlg, String sTextBoxName, String sConfigName) {
config.setOption(sConfigName, dlg.getTextFieldText(sTextBoxName));
}
protected void listBoxFromConfig(DialogAccess dlg, String sListBoxName, String sConfigName, String[] sConfigValues, short nDefault) {
String sCurrentValue = config.getOption(sConfigName);
int nCount = sConfigValues.length;
for (short i=0; i<nCount; i++) {
if (sConfigValues[i].equals(sCurrentValue)) {
dlg.setListBoxSelectedItem(sListBoxName, i);
return;
}
}
dlg.setListBoxSelectedItem(sListBoxName, nDefault);
}
protected void listBoxToConfig(DialogAccess dlg, String sListBoxName, String sConfigName, String[] sConfigValues) {
config.setOption(sConfigName, sConfigValues[dlg.getListBoxSelectedItem(sListBoxName)]);
}
// Method to get a named dialog
protected XDialog getDialog(String sDialogName) {
XMultiComponentFactory xMCF = xContext.getServiceManager();
try {
Object provider = xMCF.createInstanceWithContext(
"com.sun.star.awt.DialogProvider2", xContext);
XDialogProvider2 xDialogProvider = (XDialogProvider2)
UnoRuntime.queryInterface(XDialogProvider2.class, provider);
String sDialogUrl = "vnd.sun.star.script:"+sDialogName+"?location=application";
return xDialogProvider.createDialog(sDialogUrl);
}
catch (Exception e) {
return null;
}
}
// Method to display delete dialog
protected boolean deleteItem(String sName) {
XDialog xDialog=getDialog(getDialogLibraryName()+".DeleteDialog");
if (xDialog!=null) {
DialogAccess ddlg = new DialogAccess(xDialog);
String sLabel = ddlg.getLabelText("DeleteLabel");
sLabel = sLabel.replaceAll("%s", sName);
ddlg.setLabelText("DeleteLabel", sLabel);
boolean bDelete = xDialog.execute()==ExecutableDialogResults.OK;
xDialog.endExecute();
return bDelete;
}
return false;
}
}
protected abstract class CustomFileHandler extends PageHandler {
// The file name
private String sCustomFileName;
public CustomFileHandler() {
super();
try {
sCustomFileName = xPathSub.substituteVariables("$(user)/"+getFileName(), false);
}
catch (NoSuchElementException e) {
sCustomFileName = getFileName();
}
}
// The subclass must provide these
protected abstract String getSuffix();
protected abstract String getFileName();
protected abstract void useCustomInner(DialogAccess dlg, boolean bUseCustom);
@Override protected void setControls(DialogAccess dlg) {
String sText = "";
boolean bUseCustom = false;
if (fileExists(sCustomFileName)) {
sText = loadFile(sCustomFileName);
bUseCustom = true;
}
else if (fileExists(sCustomFileName+".bak")) {
sText = loadFile(sCustomFileName+".bak");
}
// Currently ignore failure to load the file
if (sText==null) { sText=""; }
dlg.setCheckBoxStateAsBoolean("UseCustom"+getSuffix(), bUseCustom);
dlg.setTextFieldText("Custom"+getSuffix(), sText);
useCustomChange(dlg);
}
@Override protected void getControls(DialogAccess dlg) {
if (dlg.getCheckBoxStateAsBoolean("UseCustom"+getSuffix())) {
saveFile(sCustomFileName,dlg.getTextFieldText("Custom"+getSuffix()));
killFile(sCustomFileName+".bak");
}
else {
saveFile(sCustomFileName+".bak",dlg.getTextFieldText("Custom"+getSuffix()));
killFile(sCustomFileName);
}
}
@Override protected boolean handleEvent(DialogAccess dlg, String sMethod) {
if (sMethod.equals("UseCustom"+getSuffix()+"Change")) {
useCustomChange(dlg);
return true;
}
else if (sMethod.equals("Load"+getSuffix()+"Click")) {
loadCustomClick(dlg);
return true;
}
return false;
}
private void useCustomChange(DialogAccess dlg) {
boolean bUseCustom = dlg.getCheckBoxStateAsBoolean("UseCustom"+getSuffix());
dlg.setControlEnabled("Custom"+getSuffix(), bUseCustom);
dlg.setControlEnabled("Load"+getSuffix()+"Button", bUseCustom);
useCustomInner(dlg,bUseCustom);
}
protected void loadCustomClick(DialogAccess dlg) {
String sFileName=filePicker.getPath();
if (sFileName!=null) {
String sText = loadFile(sFileName);
if (sText!=null) {
dlg.setTextFieldText("Custom"+getSuffix(), sText);
}
}
}
// Helpers for sfa2
// Checks that the file exists
protected boolean fileExists(String sFileName) {
try {
return sfa2!=null && sfa2.exists(sFileName);
}
catch (CommandAbortedException e) {
}
catch (com.sun.star.uno.Exception e) {
}
return false;
}
// Delete a file if it exists, return true on success
protected boolean killFile(String sFileName) {
try {
if (sfa2!=null && sfa2.exists(sFileName)) {
sfa2.kill(sFileName);
return true;
}
}
catch (com.sun.star.uno.Exception e) {
}
return false;
}
// Load a text file, returns null on failure
private String loadFile(String sFileName) {
if (sfa2!=null) {
try {
XInputStream xIs = sfa2.openFileRead(sFileName);
if (xIs!=null) {
InputStream is = new XInputStreamToInputStreamAdapter(xIs);
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder buf = new StringBuilder();
String sLine;
try {
while ((sLine = reader.readLine())!=null) {
buf.append(sLine).append('\n');
}
reader.close();
is.close();
}
catch (IOException e) {
}
xIs.closeInput();
return buf.toString();
}
}
catch (com.sun.star.uno.Exception e) {
}
}
return null;
}
// Save a text file, return true on success
protected boolean saveFile(String sFileName, String sText) {
killFile(sFileName);
try {
XOutputStream xOs = sfa2.openFileWrite(sFileName);
if (xOs!=null) {
OutputStream os = new XOutputStreamToOutputStreamAdapter(xOs);
try {
OutputStreamWriter osw = new OutputStreamWriter(os,"UTF-8");
osw.write(sText);
osw.flush();
os.close();
}
catch (IOException e) {
xOs.closeOutput();
return false;
}
xOs.closeOutput();
return true;
}
}
catch (com.sun.star.uno.Exception e) {
}
return false;
}
}
protected abstract class UserListPageHandler extends PageHandler {
// Methods to handle user controlled lists
protected boolean deleteCurrentItem(DialogAccess dlg, String sListName) {
String[] sItems = dlg.getListBoxStringItemList(sListName);
short nSelected = dlg.getListBoxSelectedItem(sListName);
if (nSelected>=0 && deleteItem(sItems[nSelected])) {
int nOldLen = sItems.length;
String[] sNewItems = new String[nOldLen-1];
if (nSelected>0) {
System.arraycopy(sItems, 0, sNewItems, 0, nSelected);
}
if (nSelected<nOldLen-1) {
System.arraycopy(sItems, nSelected+1, sNewItems, nSelected, nOldLen-1-nSelected);
}
dlg.setListBoxStringItemList(sListName, sNewItems);
short nNewSelected = nSelected<nOldLen-1 ? nSelected : (short)(nSelected-1);
dlg.setListBoxSelectedItem(sListName, nNewSelected);
return true;
}
return false;
}
private String newItem(Set<String> suggestions) {
XDialog xDialog=getDialog(getDialogLibraryName()+".NewDialog");
if (xDialog!=null) {
String[] sItems = Misc.sortStringSet(suggestions);
DialogAccess ndlg = new DialogAccess(xDialog);
ndlg.setListBoxStringItemList("Name", sItems);
String sResult = null;
if (xDialog.execute()==ExecutableDialogResults.OK) {
DialogAccess dlg = new DialogAccess(xDialog);
sResult = dlg.getTextFieldText("Name");
}
xDialog.endExecute();
return sResult;
}
return null;
}
protected String appendItem(DialogAccess dlg, String sListName, Set<String> suggestions) {
String[] sItems = dlg.getListBoxStringItemList(sListName);
String sNewItem = newItem(suggestions);
if (sNewItem!=null) {
int nOldLen = sItems.length;
for (short i=0; i<nOldLen; i++) {
if (sNewItem.equals(sItems[i])) {
// Item already exists, select the existing one
dlg.setListBoxSelectedItem(sListName, i);
return null;
}
}
String[] sNewItems = new String[nOldLen+1];
System.arraycopy(sItems, 0, sNewItems, 0, nOldLen);
sNewItems[nOldLen]=sNewItem;
dlg.setListBoxStringItemList(sListName, sNewItems);
dlg.setListBoxSelectedItem(sListName, (short)nOldLen);
}
return sNewItem;
}
}
protected abstract class StylesPageHandler extends UserListPageHandler {
// The subclass must define these
protected String[] sFamilyNames;
protected String[] sOOoFamilyNames;
// Our data
private ComplexOption[] styleMap;
protected short nCurrentFamily = -1;
private String sCurrentStyleName = null;
// Access to display names of the styles in the current document
protected StyleNameProvider styleNameProvider = null;
// Some methods to be implemented by the subclass
protected abstract String getDefaultConfigName();
protected abstract void getControls(DialogAccess dlg, Map<String,String> attr);
protected abstract void setControls(DialogAccess dlg, Map<String,String> attr);
protected abstract void clearControls(DialogAccess dlg);
protected abstract void prepareControls(DialogAccess dlg, boolean bHasDefinitions);
// Constructor
protected StylesPageHandler(int nCount) {
// Get the style name provider
styleNameProvider = new StyleNameProvider(xContext);
// Reset the options
styleMap = new ComplexOption[nCount];
for (int i=0; i<nCount; i++) {
styleMap[i] = new ComplexOption();
}
}
// Implement abstract methods from super
protected void setControls(DialogAccess dlg) {
// Load style maps from config (translating keys to display names)
int nCount = sFamilyNames.length;
for (int i=0; i<nCount; i++) {
ComplexOption configMap = config.getComplexOption(sFamilyNames[i]+"-map");
styleMap[i].clear();
Map<String,String> displayNames = styleNameProvider.getDisplayNames(sOOoFamilyNames[i]);
copyStyles(configMap, styleMap[i], displayNames);
}
// Display paragraph maps first
nCurrentFamily = -1;
sCurrentStyleName = null;
dlg.setListBoxSelectedItem("StyleFamily", (short)1);
styleFamilyChange(dlg);
}
protected void getControls(DialogAccess dlg) {
updateStyleMaps(dlg);
// Save style maps to config (translating keys back to internal names)
int nCount = sFamilyNames.length;
for (int i=0; i<nCount; i++) {
ComplexOption configMap = config.getComplexOption(sFamilyNames[i]+"-map");
configMap.clear();
Map<String,String> internalNames = styleNameProvider.getInternalNames(sOOoFamilyNames[i]);
copyStyles(styleMap[i], configMap, internalNames);
}
}
protected boolean handleEvent(DialogAccess dlg, String sMethod) {
if (sMethod.equals("StyleFamilyChange")) {
styleFamilyChange(dlg);
return true;
}
else if (sMethod.equals("StyleNameChange")) {
styleNameChange(dlg);
return true;
}
else if (sMethod.equals("NewStyleClick")) {
newStyleClick(dlg);
return true;
}
else if (sMethod.equals("DeleteStyleClick")) {
deleteStyleClick(dlg);
return true;
}
else if (sMethod.equals("LoadDefaultsClick")) {
loadDefaultsClick(dlg);
return true;
}
return false;
}
// Internal methods
private void updateStyleMaps(DialogAccess dlg) {
// Save the current style map, if any
if (nCurrentFamily>-1 && sCurrentStyleName!=null) {
getControls(dlg,styleMap[nCurrentFamily].get(sCurrentStyleName));
}
}
private void styleFamilyChange(DialogAccess dlg) {
short nNewFamily = dlg.getListBoxSelectedItem("StyleFamily");
if (nNewFamily>-1 && nNewFamily!=nCurrentFamily) {
// The user has changed the family; load and display the corresponding style names
updateStyleMaps(dlg);
nCurrentFamily = nNewFamily;
sCurrentStyleName = null;
String[] sStyleNames = Misc.sortStringSet(styleMap[nNewFamily].keySet());
dlg.setListBoxStringItemList("StyleName", sStyleNames);
if (sStyleNames.length>0) {
dlg.setListBoxSelectedItem("StyleName", (short)0);
}
else {
dlg.setListBoxSelectedItem("StyleName", (short)-1);
}
updateStyleControls(dlg);
styleNameChange(dlg);
}
}
private void styleNameChange(DialogAccess dlg) {
if (nCurrentFamily>-1) {
updateStyleMaps(dlg);
short nStyleNameItem = dlg.getListBoxSelectedItem("StyleName");
if (nStyleNameItem>=0) {
sCurrentStyleName = dlg.getListBoxStringItemList("StyleName")[nStyleNameItem];
setControls(dlg,styleMap[nCurrentFamily].get(sCurrentStyleName));
}
else {
sCurrentStyleName = null;
clearControls(dlg);
}
}
}
private void newStyleClick(DialogAccess dlg) {
if (nCurrentFamily>-1) {
updateStyleMaps(dlg);
// Invalidate current style name in any case (appendItem returns null if the user
// selects an existing style, but it still changes the current item)
sCurrentStyleName = null;
String sNewName = appendItem(dlg, "StyleName",styleNameProvider.getInternalNames(sOOoFamilyNames[nCurrentFamily]).keySet());
if (sNewName!=null) {
styleMap[nCurrentFamily].put(sNewName, new HashMap<String,String>());
clearControls(dlg);
}
styleNameChange(dlg);
updateStyleControls(dlg);
}
}
private void deleteStyleClick(DialogAccess dlg) {
if (nCurrentFamily>-1 && sCurrentStyleName!=null) {
String sStyleName = sCurrentStyleName;
if (deleteCurrentItem(dlg,"StyleName")) {
styleMap[nCurrentFamily].remove(sStyleName);
sCurrentStyleName=null;
styleNameChange(dlg);
}
updateStyleControls(dlg);
}
}
private void loadDefaultsClick(DialogAccess dlg) {
updateStyleMaps(dlg);
// Count styles that we will overwrite
Config clean = ConverterFactory.createConverter(getMIMEType()).getConfig();
clean.readDefaultConfig(getDefaultConfigName());
int nCount = 0;
int nFamilyCount = sFamilyNames.length;
for (int i=0; i<nFamilyCount; i++) {
ComplexOption cleanMap = clean.getComplexOption(sFamilyNames[i]+"-map");
Map<String,String> displayNames = styleNameProvider.getDisplayNames(sOOoFamilyNames[i]);
for (String sName : cleanMap.keySet()) {
String sDisplayName = (displayNames!=null && displayNames.containsKey(sName)) ? displayNames.get(sName) : "";
if (styleMap[i].containsKey(sDisplayName)) { nCount++; }
}
}
// Display confirmation dialog
boolean bConfirm = false;
XDialog xDialog=getDialog(getDialogLibraryName()+".LoadDefaults");
if (xDialog!=null) {
DialogAccess ldlg = new DialogAccess(xDialog);
if (nCount>0) {
String sLabel = ldlg.getLabelText("OverwriteLabel");
sLabel = sLabel.replaceAll("%s", Integer.toString(nCount));
ldlg.setLabelText("OverwriteLabel", sLabel);
}
else {
ldlg.setLabelText("OverwriteLabel", "");
}
bConfirm = xDialog.execute()==ExecutableDialogResults.OK;
xDialog.endExecute();
}
// Do the replacement
if (bConfirm) {
for (int i=0; i<nFamilyCount; i++) {
ComplexOption cleanMap = clean.getComplexOption(sFamilyNames[i]+"-map");
Map<String,String> displayNames = styleNameProvider.getDisplayNames(sOOoFamilyNames[i]);
copyStyles(cleanMap, styleMap[i], displayNames);
}
}
// Force update of the user interface
nCurrentFamily = -1;
sCurrentStyleName = null;
styleFamilyChange(dlg);
}
private void updateStyleControls(DialogAccess dlg) {
boolean bHasMappings = dlg.getListBoxStringItemList("StyleName").length>0;
dlg.setControlEnabled("DeleteStyleButton", bHasMappings);
prepareControls(dlg,bHasMappings);
}
private void copyStyles(ComplexOption source, ComplexOption target, Map<String,String> nameTranslation) {
for (String sName : source.keySet()) {
String sNewName = sName;
if (nameTranslation!=null && nameTranslation.containsKey(sName)) {
sNewName = nameTranslation.get(sName);
}
target.copy(sNewName, source.get(sName));
}
}
}
protected abstract class AttributePageHandler extends PageHandler {
// The subclass must define this
protected String[] sAttributeNames;
// Our data
private ComplexOption attributeMap = new ComplexOption();
private int nCurrentAttribute = -1;
// Some methods to be implemented by subclass
protected abstract void getControls(DialogAccess dlg, Map<String,String> attr);
protected abstract void setControls(DialogAccess dlg, Map<String,String> attr);
protected abstract void prepareControls(DialogAccess dlg, boolean bEnable);
// Implement abstract methods from our super
protected void setControls(DialogAccess dlg) {
// Load attribute maps from config
attributeMap.clear();
attributeMap.copyAll(config.getComplexOption("text-attribute-map"));
// Update the dialog
nCurrentAttribute = -1;
dlg.setListBoxSelectedItem("FormattingAttribute", (short)0);
formattingAttributeChange(dlg);
}
protected void getControls(DialogAccess dlg) {
updateAttributeMaps(dlg);
// Save attribute maps to config
ComplexOption configMap = config.getComplexOption("text-attribute-map");
configMap.clear();
for (String s: attributeMap.keySet()) {
Map<String,String> attr = attributeMap.get(s);
if (!attr.containsKey("deleted") || attr.get("deleted").equals("false")) {
configMap.copy(s, attr);
}
}
}
protected boolean handleEvent(DialogAccess dlg, String sMethod) {
if (sMethod.equals("FormattingAttributeChange")) {
formattingAttributeChange(dlg);
return true;
}
else if (sMethod.equals("CustomAttributeChange")) {
customAttributeChange(dlg);
return true;
}
return false;
}
// Internal methods
private void updateAttributeMaps(DialogAccess dlg) {
// Save the current attribute map, if any
if (nCurrentAttribute>-1) {
String sName = sAttributeNames[nCurrentAttribute];
if (!attributeMap.containsKey(sName)) {
attributeMap.put(sName, new HashMap<String,String>());
}
Map<String,String> attr = attributeMap.get(sName);
attr.put("deleted", Boolean.toString(!dlg.getCheckBoxStateAsBoolean("CustomAttribute")));
getControls(dlg,attr);
attributeMap.put(sName, attr);
}
}
private void formattingAttributeChange(DialogAccess dlg) {
updateAttributeMaps(dlg);
short nNewAttribute = dlg.getListBoxSelectedItem("FormattingAttribute");
if (nNewAttribute>-1 && nNewAttribute!=nCurrentAttribute) {
nCurrentAttribute = nNewAttribute;
String sName = sAttributeNames[nCurrentAttribute];
if (!attributeMap.containsKey(sName)) {
attributeMap.put(sName, new HashMap<String,String>());
attributeMap.get(sName).put("deleted", "true");
}
Map<String,String> attr = attributeMap.get(sName);
dlg.setCheckBoxStateAsBoolean("CustomAttribute", !attr.containsKey("deleted") || attr.get("deleted").equals("false"));
customAttributeChange(dlg);
setControls(dlg,attr);
}
}
private void customAttributeChange(DialogAccess dlg) {
prepareControls(dlg,dlg.getCheckBoxStateAsBoolean("CustomAttribute"));
}
}
}

View file

@ -0,0 +1,86 @@
/************************************************************************
*
* EPSCleaner.java
*
* Copyright: 2002-2009 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.0 (2009-03-09)
*/
package org.openoffice.da.comp.w2lcommon.filter;
/** This class removes redundant binary information from EPS files created by OOo.
* See the issue http://qa.openoffice.org/issues/show_bug.cgi?id=25256
* According to this message http://markmail.org/message/dc6rprmtktxuq35v
* on dev@openoffice.org the binary data is an EPSI preview in TIFF format
* TODO: Is it possible to avoid this export?
*/
public class EPSCleaner {
// Signatures for start and end in eps
private byte[] psStart;
private byte[] psEnd;
public EPSCleaner() {
try {
psStart = "%!PS-Adobe".getBytes("US-ASCII");
psEnd = "%%EOF".getBytes("US-ASCII");
}
catch (java.io.UnsupportedEncodingException ex) {
// US-ASCII *is* supported :-)
}
}
//
public byte[] cleanEps(byte[] blob) {
int n = blob.length;
int nStart = 0;
for (int i=0; i<n; i++) {
if (match(blob,psStart,i)) {
nStart=i;
break;
}
}
int nEnd = n;
for (int i=nStart; i<n; i++) {
if (match(blob,psEnd,i)) {
nEnd=i+psEnd.length;
break;
}
}
byte[] newBlob = new byte[nEnd-nStart];
System.arraycopy(blob,nStart,newBlob,0,nEnd-nStart);
return newBlob;
}
private boolean match(byte[] blob, byte[] sig, int nStart) {
int n = sig.length;
if (nStart+n>=blob.length) { return false; }
for (int i=0; i<n; i++) {
if (blob[nStart+i]!=sig[i]) { return false; }
}
return true;
}
}

View file

@ -0,0 +1,185 @@
/************************************************************************
*
* ExportFilterBase.java
*
* Copyright: 2002-2014 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2014-10-06)
*
*/
package org.openoffice.da.comp.w2lcommon.filter;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.lang.XServiceName;
import com.sun.star.lang.XTypeProvider;
import com.sun.star.uno.Type;
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.util.SimpleDOMBuilder;
import java.io.IOException;
/** This class provides an abstract UNO component which implements an XExportFilter.
* The filter is actually generic and only the constructor and 3 strings needs
* to be changed by the subclass.
*/
public abstract class ExportFilterBase implements
XExportFilter,
XServiceName,
XServiceInfo,
XDocumentHandler,
XTypeProvider {
/** Service name for the component */
public static final String __serviceName = "";
/** Implementation name for the component */
public static final String __implementationName = "";
/** Filter name to include in error messages */
public String __displayName = "";
private XComponentContext xComponentContext = null;
private SimpleDOMBuilder domBuilder = new SimpleDOMBuilder();
private UNOConverter converter = null;
/** Construct a new ExportFilterBase from a given component context
*
* @param xComponentContext the component context used to instantiate new UNO services
*/
public ExportFilterBase(XComponentContext xComponentContext) {
this.xComponentContext = xComponentContext;
}
// ---------------------------------------------------------------------------
// Implementation of XExportFilter:
public boolean exporter(com.sun.star.beans.PropertyValue[] aSourceData,
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
public void startDocument () {
//Do nothing
}
public void endDocument()throws com.sun.star.uno.RuntimeException {
try{
converter.convert(domBuilder.getDOM());
}
catch (IOException e){
MessageBox msgBox = new MessageBox(xComponentContext);
msgBox.showMessage(__displayName+": IO error in conversion",
e.toString()+" at "+e.getStackTrace()[0].toString());
throw new com.sun.star.uno.RuntimeException(e.getMessage());
}
catch (Exception e){
MessageBox msgBox = new MessageBox(xComponentContext);
msgBox.showMessage(__displayName+": Internal error in conversion",
e.toString()+" at "+e.getStackTrace()[0].toString());
throw new com.sun.star.uno.RuntimeException(__displayName+" Exception");
}
}
public void startElement (String sTagName, com.sun.star.xml.sax.XAttributeList xAttribs) {
domBuilder.startElement(sTagName);
int nLen = xAttribs.getLength();
for (short i=0;i<nLen;i++) {
domBuilder.setAttribute(xAttribs.getNameByIndex(i), xAttribs.getValueByIndex(i));
}
}
public void endElement(String sTagName){
domBuilder.endElement();
}
public void characters(String sText){
domBuilder.characters(sText);
}
public void ignorableWhitespace(String str){
}
public void processingInstruction(String aTarget, String aData){
}
public void setDocumentLocator(com.sun.star.xml.sax.XLocator xLocator){
}
// ---------------------------------------------------------------------------
// Implement methods from interface XTypeProvider
public com.sun.star.uno.Type[] getTypes() {
Type[] typeReturn = {};
try {
typeReturn = new Type[] {
new Type( XTypeProvider.class ),
new Type( XExportFilter.class ),
new Type( XServiceName.class ),
new Type( XServiceInfo.class ) };
}
catch( Exception exception ) {
}
return( typeReturn );
}
public byte[] getImplementationId() {
byte[] byteReturn = {};
byteReturn = new String( "" + this.hashCode() ).getBytes();
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 ) );
}
public String getImplementationName() {
return __implementationName;
}
public String[] getSupportedServiceNames() {
String[] stringSupportedServiceNames = { __serviceName };
return( stringSupportedServiceNames );
}
}

View file

@ -0,0 +1,432 @@
/************************************************************************
*
* FilterDataParser.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-05-06)
*
*/
package org.openoffice.da.comp.w2lcommon.filter;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Enumeration;
import com.sun.star.beans.PropertyValue;
import com.sun.star.io.NotConnectedException;
import com.sun.star.io.XInputStream;
import com.sun.star.io.XOutputStream;
import com.sun.star.ucb.CommandAbortedException;
import com.sun.star.ucb.XSimpleFileAccess2;
import com.sun.star.uno.AnyConverter;
import com.sun.star.uno.Exception;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.util.XStringSubstitution;
import com.sun.star.lib.uno.adapter.XInputStreamToInputStreamAdapter;
import com.sun.star.lib.uno.adapter.XOutputStreamToOutputStreamAdapter;
import org.openoffice.da.comp.w2lcommon.helper.PropertyHelper;
import writer2latex.api.Converter;
/** This class parses the FilterData property passed to the filter and
* applies it to a <code>Converter</code>
* All errors are silently ignored
*/
public class FilterDataParser {
// TODO: Use JSON format
//private static XComponentContext xComponentContext = null;
private XSimpleFileAccess2 sfa2;
private XStringSubstitution xPathSub;
public FilterDataParser(XComponentContext xComponentContext) {
//this.xComponentContext = xComponentContext;
// Get the SimpleFileAccess service
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)
}
// Get the PathSubstitution service
xPathSub = null;
try {
Object psObject = xComponentContext.getServiceManager().createInstanceWithContext(
"com.sun.star.util.PathSubstitution", xComponentContext);
xPathSub = (XStringSubstitution) UnoRuntime.queryInterface(XStringSubstitution.class, psObject);
}
catch (com.sun.star.uno.Exception e) {
// failed to get PathSubstitution service (should not happen)
}
}
/** Apply the given FilterOptions property to the given converter.
* The property must be a comma separated list of name=value items.
* @param options an <code>Any</code> containing the FilterOptions property
* @param converter a <code>writer2latex.api.Converter</code> implementation
*/
public void applyFilterOptions(Object options, Converter converter) {
// Get the string from the data, if possible
if (AnyConverter.isString(options)) {
String sOptions = AnyConverter.toString(options);
if (sOptions!=null) {
// Convert to array
String[] sItems = sOptions.split(",");
int nItemCount = sItems.length;
PropertyValue[] filterData = new PropertyValue[nItemCount];
for (int i=0; i<nItemCount; i++) {
String[] sItem = sItems[i].split("=");
filterData[i] = new PropertyValue();
filterData[i].Name = sItem[0];
filterData[i].Value = sItem.length>1 ? sItem[1] : "";
System.out.println(filterData[i].Name+" "+filterData[i].Value);
}
applyParsedFilterData(filterData,converter);
}
}
}
/** Apply the given FilterData property to the given converter.
* The property must be an array of PropertyValue objects.
* @param data an <code>Any</code> containing the FilterData property
* @param converter a <code>writer2latex.api.Converter</code> implementation
*/
public void applyFilterData(Object data, Converter converter) {
// Get the array from the data, if possible
PropertyValue[] filterData = null;
if (AnyConverter.isArray(data)) {
try {
Object[] arrayData = (Object[]) AnyConverter.toArray(data);
if (arrayData instanceof PropertyValue[]) {
filterData = (PropertyValue[]) arrayData;
if (filterData!=null) {
applyParsedFilterData(filterData,converter);
}
}
}
catch (com.sun.star.lang.IllegalArgumentException e) {
// Failed to convert to array; should not happen - ignore
}
}
}
private void applyParsedFilterData(PropertyValue[] filterData, Converter converter) {
PropertyHelper props = new PropertyHelper(filterData);
// Get the special properties TemplateURL, StyleSheetURL, ResourceURL, Resources, ConfigURL and AutoCreate
Object tpl = props.get("TemplateURL");
String sTemplate = null;
if (tpl!=null && AnyConverter.isString(tpl)) {
try {
sTemplate = substituteVariables(AnyConverter.toString(tpl));
}
catch (com.sun.star.lang.IllegalArgumentException e) {
// Failed to convert to String; should not happen - ignore
}
}
Object styles = props.get("StyleSheetURL");
String sStyleSheet = null;
if (styles!=null && AnyConverter.isString(styles)) {
try {
sStyleSheet = substituteVariables(AnyConverter.toString(styles));
}
catch (com.sun.star.lang.IllegalArgumentException e) {
// Failed to convert to String; should not happen - ignore
}
}
// This property accepts an URL pointing to a folder containing the resources to include
Object resourcedir = props.get("ResourceURL");
String sResourceURL = null;
if (resourcedir!=null && AnyConverter.isString(resourcedir)) {
try {
sResourceURL = substituteVariables(AnyConverter.toString(resourcedir));
}
catch (com.sun.star.lang.IllegalArgumentException e) {
// Failed to convert to String; should not happen - ignore
}
}
// This property accepts a semicolon separated list of <URL>[[::<file name>]::<mime type>]
Object resources = props.get("Resources");
String[] sResources = null;
if (resources!=null && AnyConverter.isString(resources)) {
try {
sResources = substituteVariables(AnyConverter.toString(resources)).split(";");
}
catch (com.sun.star.lang.IllegalArgumentException e) {
// Failed to convert to String; should not happen - ignore
}
}
Object auto = props.get("AutoCreate");
boolean bAutoCreate = false;
if (auto!=null && AnyConverter.isString(auto)) {
try {
if ("true".equals(AnyConverter.toString(auto))) {
bAutoCreate = true;
}
}
catch (com.sun.star.lang.IllegalArgumentException e) {
// Failed to convert to String; should not happen - ignore
}
}
Object cfg = props.get("ConfigURL");
String sConfig = null;
if (cfg!=null && AnyConverter.isString(cfg)) {
try {
sConfig = substituteVariables(AnyConverter.toString(cfg));
}
catch (com.sun.star.lang.IllegalArgumentException e) {
// Failed to convert to String; should not happen - ignore
}
}
// Load the template from the specified URL, if any
if (sfa2!=null && sTemplate!=null && sTemplate.length()>0) {
try {
XInputStream xIs = sfa2.openFileRead(sTemplate);
if (xIs!=null) {
InputStream is = new XInputStreamToInputStreamAdapter(xIs);
converter.readTemplate(is);
is.close();
xIs.closeInput();
}
}
catch (IOException e) {
// ignore
}
catch (NotConnectedException e) {
// ignore
}
catch (CommandAbortedException e) {
// ignore
}
catch (com.sun.star.uno.Exception e) {
// ignore
}
}
// Load the style sheet from the specified URL, if any
if (sfa2!=null && sStyleSheet!=null && sStyleSheet.length()>0) {
try {
XInputStream xIs = sfa2.openFileRead(sStyleSheet);
if (xIs!=null) {
InputStream is = new XInputStreamToInputStreamAdapter(xIs);
converter.readStyleSheet(is);
is.close();
xIs.closeInput();
}
}
catch (IOException e) {
// ignore
}
catch (NotConnectedException e) {
// ignore
}
catch (CommandAbortedException e) {
// ignore
}
catch (com.sun.star.uno.Exception e) {
// ignore
}
}
// Load the resource from the specified folder URL, if any
if (sfa2!=null && sResourceURL!=null && sResourceURL.length()>0) {
String[] sURLs;
try {
sURLs = sfa2.getFolderContents(sResourceURL, false); // do not include folders
for (String sURL : sURLs) {
XInputStream xIs = sfa2.openFileRead(sURL);
if (xIs!=null) {
String sFileName = sURL.substring(sURL.lastIndexOf('/')+1);
InputStream is = new XInputStreamToInputStreamAdapter(xIs);
converter.readResource(is,sFileName,null);
is.close();
xIs.closeInput();
}
}
} catch (IOException e) {
// ignore
} catch (CommandAbortedException e1) {
// ignore
} catch (Exception e1) {
// ignore
}
}
// Load the resources from the specified URLs, if any
if (sfa2!=null && sResources!=null) {
for (String sResource : sResources) {
// Format is <URL>[[::<file name>]::<mime type>]
String[] sParts = sResource.split("::");
if (sParts.length>0) {
String sURL=sParts[0];
String sFileName;
String sMediaType=null;
if (sParts.length==3) {
sFileName = sParts[1];
sMediaType = sParts[2];
}
else {
sFileName = sURL.substring(sURL.lastIndexOf('/')+1);
if (sParts.length==2) {
sMediaType = sParts[1];
}
}
try {
XInputStream xIs = sfa2.openFileRead(sURL);
if (xIs!=null) {
InputStream is = new XInputStreamToInputStreamAdapter(xIs);
converter.readResource(is, sFileName, sMediaType);
is.close();
xIs.closeInput();
} // otherwise wrong format, ignore
}
catch (IOException e) {
// ignore
}
catch (NotConnectedException e) {
// ignore
}
catch (CommandAbortedException e) {
// ignore
}
catch (com.sun.star.uno.Exception e) {
// ignore
}
}
}
}
// Create config if required
try {
if (bAutoCreate && sfa2!=null && sConfig!=null && !sConfig.startsWith("*") && !sfa2.exists(sConfig)) {
// Note: Requires random access, ie. must be a file URL:
XOutputStream xOs = sfa2.openFileWrite(sConfig);
if (xOs!=null) {
OutputStream os = new XOutputStreamToOutputStreamAdapter(xOs);
converter.getConfig().write(os);
os.flush();
os.close();
xOs.closeOutput();
}
}
}
catch (IOException e) {
// ignore
}
catch (NotConnectedException e) {
// ignore
}
catch (CommandAbortedException e) {
// Ignore
}
catch (com.sun.star.uno.Exception e) {
// Ignore
}
// Load the configuration from the specified URL, if any
if (sConfig!=null) {
if (sConfig.startsWith("*")) { // internal configuration
try {
converter.getConfig().readDefaultConfig(sConfig.substring(1));
}
catch (IllegalArgumentException e) {
// ignore
}
}
else if (sfa2!=null) { // real URL
try {
XInputStream xIs = sfa2.openFileRead(sConfig);;
if (xIs!=null) {
InputStream is = new XInputStreamToInputStreamAdapter(xIs);
converter.getConfig().read(is);
is.close();
xIs.closeInput();
}
}
catch (IOException e) {
// Ignore
}
catch (NotConnectedException e) {
// Ignore
}
catch (CommandAbortedException e) {
// Ignore
}
catch (com.sun.star.uno.Exception e) {
// Ignore
}
}
}
// Read further configuration properties
Enumeration<String> keys = props.keys();
while (keys.hasMoreElements()) {
String sKey = keys.nextElement();
if (!"ConfigURL".equals(sKey) && !"TemplateURL".equals(sKey) && !"StyleSheetURL".equals(sKey)
&& !"Resources".equals(sKey) && !"AutoCreate".equals(sKey)) {
Object value = props.get(sKey);
if (AnyConverter.isString(value)) {
try {
converter.getConfig().setOption(sKey,AnyConverter.toString(value));
}
catch (com.sun.star.lang.IllegalArgumentException e) {
// Failed to convert to String; should not happen - ignore
}
}
}
}
}
private String substituteVariables(String sUrl) {
if (xPathSub!=null) {
try {
return xPathSub.substituteVariables(sUrl, false);
}
catch (com.sun.star.container.NoSuchElementException e) {
// Found an unknown variable, no substitution
// (This will only happen if false is replaced by true above)
return sUrl;
}
}
else { // Not path substitution available
return sUrl;
}
}
}

View file

@ -0,0 +1,66 @@
/************************************************************************
*
* GraphicConverterImpl.java
*
* Copyright: 2002-2008 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.0 (2008-07-21)
*
*/
package org.openoffice.da.comp.w2lcommon.filter;
import com.sun.star.uno.XComponentContext;
import writer2latex.api.GraphicConverter;
public class GraphicConverterImpl implements GraphicConverter {
private GraphicConverter graphicConverter1;
private GraphicConverter graphicConverter2;
public GraphicConverterImpl(XComponentContext xComponentContext) {
graphicConverter1 = new GraphicConverterImpl1(xComponentContext);
graphicConverter2 = new GraphicConverterImpl2(xComponentContext);
}
public boolean supportsConversion(String sSourceMime, String sTargetMime, boolean bCrop, boolean bResize) {
return graphicConverter1.supportsConversion(sSourceMime, sTargetMime, bCrop, bResize) ||
graphicConverter2.supportsConversion(sSourceMime, sTargetMime, bCrop, bResize);
}
public byte[] convert(byte[] source, String sSourceMime, String sTargetMime) {
byte[] result = null;
// Prefer the simple implementation (GraphicProvider)
if (graphicConverter1.supportsConversion(sSourceMime, sTargetMime, false, false)) {
result = graphicConverter1.convert(source, sSourceMime, sTargetMime);
}
// If this is not possible or fails, try the complex implementation
if (result==null) {
result = graphicConverter2.convert(source, sSourceMime, sTargetMime);
}
return result;
}
}

View file

@ -0,0 +1,155 @@
/************************************************************************
*
* GraphicConverterImpl1.java
*
* Copyright: 2002-2014 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.4 (2014-09-05)
*/
package org.openoffice.da.comp.w2lcommon.filter;
// Java uno helper class
import com.sun.star.lib.uno.adapter.ByteArrayToXInputStreamAdapter;
// UNO classes
import com.sun.star.beans.PropertyValue;
import com.sun.star.graphic.XGraphic;
import com.sun.star.graphic.XGraphicProvider;
//import com.sun.star.io.XInputStream;
//import com.sun.star.io.XOutputStream;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.uno.XComponentContext;
import com.sun.star.uno.UnoRuntime;
//import java.io.InputStream;
//import java.io.OutputStream;
import writer2latex.api.GraphicConverter;
import writer2latex.api.MIMETypes;
/** A GraphicConverter implementation which uses the GraphicProvider service
* to convert the graphic. This service does only support simple format
* conversion using the "internal" graphics filters in Draw. Advanced features
* like pdf, crop and resize thus cannot be handled.
*/
public class GraphicConverterImpl1 implements GraphicConverter {
private XGraphicProvider xGraphicProvider;
private EPSCleaner epsCleaner;
public GraphicConverterImpl1(XComponentContext xComponentContext) {
try {
// Get the XGraphicProvider interface of the GraphicProvider service
XMultiComponentFactory xMCF = xComponentContext.getServiceManager();
Object graphicProviderObject = xMCF.createInstanceWithContext("com.sun.star.graphic.GraphicProvider", xComponentContext);
xGraphicProvider = (XGraphicProvider) UnoRuntime.queryInterface(XGraphicProvider.class, graphicProviderObject);
}
catch (com.sun.star.uno.Exception ex) {
System.err.println("Failed to get XGraphicProvider object");
xGraphicProvider = null;
}
epsCleaner = new EPSCleaner();
}
public boolean supportsConversion(String sSourceMime, String sTargetMime, boolean bCrop, boolean bResize) {
// We don't support cropping and resizing
if (bCrop || bResize) { return false; }
// We can convert vector formats to EPS and SVG
if ((MIMETypes.EPS.equals(sTargetMime) || MIMETypes.SVG.equals(sTargetMime)) &&
(MIMETypes.EMF.equals(sSourceMime) || MIMETypes.WMF.equals(sSourceMime) || MIMETypes.SVM.equals(sSourceMime))) {
return true;
}
// And we can convert all formats to bitmaps
boolean bSupportsSource =
MIMETypes.PNG.equals(sSourceMime) || MIMETypes.JPEG.equals(sSourceMime) ||
MIMETypes.GIF.equals(sSourceMime) || MIMETypes.TIFF.equals(sSourceMime) ||
MIMETypes.BMP.equals(sSourceMime) || MIMETypes.EMF.equals(sSourceMime) ||
MIMETypes.WMF.equals(sSourceMime) || MIMETypes.SVM.equals(sSourceMime);
boolean bSupportsTarget =
MIMETypes.PNG.equals(sTargetMime) || MIMETypes.JPEG.equals(sTargetMime) ||
MIMETypes.GIF.equals(sTargetMime) || MIMETypes.TIFF.equals(sTargetMime) ||
MIMETypes.BMP.equals(sTargetMime);
return bSupportsSource && bSupportsTarget;
}
public byte[] convert(byte[] source, String sSourceMime, String sTargetMime) {
// It seems that the GraphicProvider can only create proper eps if
// the source is a vector format, hence
if (MIMETypes.EPS.equals(sTargetMime)) {
if (!MIMETypes.EMF.equals(sSourceMime) && !MIMETypes.WMF.equals(sSourceMime) && !MIMETypes.SVM.equals(sSourceMime)) {
return null;
}
}
ByteArrayToXInputStreamAdapter xSource = new ByteArrayToXInputStreamAdapter(source);
ByteArrayXStream xTarget = new ByteArrayXStream();
try {
// Read the source
PropertyValue[] sourceProps = new PropertyValue[1];
sourceProps[0] = new PropertyValue();
sourceProps[0].Name = "InputStream";
sourceProps[0].Value = xSource;
XGraphic result = xGraphicProvider.queryGraphic(sourceProps);
// Store as new type
PropertyValue[] targetProps = new PropertyValue[2];
targetProps[0] = new PropertyValue();
targetProps[0].Name = "MimeType";
targetProps[0].Value = sTargetMime;
targetProps[1] = new PropertyValue();
targetProps[1].Name = "OutputStream";
targetProps[1].Value = xTarget;
xGraphicProvider.storeGraphic(result,targetProps);
// Close the output and return the result
xTarget.flush();
xTarget.closeOutput();
if (MIMETypes.EPS.equals(sTargetMime)) {
return epsCleaner.cleanEps(xTarget.getBuffer());
}
else {
byte[] converted = xTarget.getBuffer();
if (converted.length>0) { // Older versions of AOO/LO fails to convert to SVG (empty result)
return converted;
}
return null;
}
}
catch (com.sun.star.io.IOException e) {
return null;
}
catch (com.sun.star.lang.IllegalArgumentException e) {
return null;
}
catch (com.sun.star.lang.WrappedTargetException e) {
return null;
}
catch (Throwable e) {
return null;
}
}
}

View file

@ -0,0 +1,267 @@
/************************************************************************
*
* GraphicConverterImpl2.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-07-30)
*
*/
package org.openoffice.da.comp.w2lcommon.filter;
import java.util.Hashtable;
import com.sun.star.awt.Point;
import com.sun.star.awt.Size;
import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.XPropertySet;
import com.sun.star.drawing.XDrawPage;
import com.sun.star.drawing.XDrawPages;
import com.sun.star.drawing.XDrawPagesSupplier;
import com.sun.star.drawing.XShape;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.frame.XStorable;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.uno.XComponentContext;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.util.XRefreshable;
import com.sun.star.lib.uno.adapter.ByteArrayToXInputStreamAdapter;
import com.sun.star.lib.uno.adapter.XOutputStreamToByteArrayAdapter;
import writer2latex.api.GraphicConverter;
import writer2latex.api.MIMETypes;
/** A GraphicConverter implementation which uses a hidden Draw document to
* store the graphic, providing more control over the image than the
* simple GraphicProvider implementation.
*/
public class GraphicConverterImpl2 implements GraphicConverter {
private XComponentContext xComponentContext;
private Hashtable<String,String> importFilter;
private Hashtable<String,String> exportFilter;
private EPSCleaner epsCleaner;
public GraphicConverterImpl2(XComponentContext xComponentContext) {
this.xComponentContext = xComponentContext;
importFilter = new Hashtable<String,String>();
importFilter.put(MIMETypes.BMP, "BMP - MS Windows");
importFilter.put(MIMETypes.EMF, "EMF - MS Windows Metafile");
importFilter.put(MIMETypes.EPS, "EPS - Encapsulated PostScript");
importFilter.put(MIMETypes.GIF, "GIF - Graphics Interchange Format");
importFilter.put(MIMETypes.JPEG, "JPG - JPEG");
importFilter.put(MIMETypes.PNG, "PNG - Portable Network Graphic");
importFilter.put(MIMETypes.SVM, "SVM - StarView Metafile");
importFilter.put(MIMETypes.TIFF, "TIF - Tag Image File");
importFilter.put(MIMETypes.WMF, "WMF - MS Windows Metafile");
exportFilter = new Hashtable<String,String>();
exportFilter.put(MIMETypes.BMP,"draw_bmp_Export");
exportFilter.put(MIMETypes.EMF,"draw_emf_Export");
exportFilter.put(MIMETypes.EPS,"draw_eps_Export");
exportFilter.put(MIMETypes.GIF,"draw_gif_Export");
exportFilter.put(MIMETypes.JPEG,"draw_jpg_Export");
exportFilter.put(MIMETypes.PNG,"draw_png_Export");
exportFilter.put(MIMETypes.SVG,"draw_svg_Export");
exportFilter.put(MIMETypes.SVM,"draw_svm_Export");
exportFilter.put(MIMETypes.TIFF,"draw_tif_Export");
exportFilter.put(MIMETypes.WMF,"draw_wmf_Export");
exportFilter.put(MIMETypes.PDF,"draw_pdf_Export");
epsCleaner = new EPSCleaner();
}
public boolean supportsConversion(String sSourceMime, String sTargetMime, boolean bCrop, boolean bResize) {
// We don't support cropping and resizing
if (bCrop || bResize) { return false; }
// We currently support conversion of bitmaps and SVM into PDF, EPS and SVG
// TODO: SVG does not seem to work in all versions of OOo/LO?
// Trying WMF/EMF causes an IllegalArgumentException "URL seems to be an unsupported one"
// Seems to be an OOo bug; workaround: Use temporary files..??
boolean bSupportsSource = MIMETypes.SVM.equals(sSourceMime) ||
MIMETypes.PNG.equals(sSourceMime) || MIMETypes.JPEG.equals(sSourceMime) ||
MIMETypes.GIF.equals(sSourceMime) || MIMETypes.TIFF.equals(sSourceMime) ||
MIMETypes.BMP.equals(sSourceMime)
|| MIMETypes.WMF.equals(sSourceMime) || MIMETypes.EMF.equals(sSourceMime);
boolean bSupportsTarget = MIMETypes.PDF.equals(sTargetMime) || MIMETypes.EPS.equals(sTargetMime) ||
MIMETypes.SVG.equals(sTargetMime);
return bSupportsSource && bSupportsTarget;
}
public byte[] convert(byte[] source, String sSourceMime, String sTargetMime) {
// Open a hidden sdraw document
XMultiComponentFactory xMCF = xComponentContext.getServiceManager();
try {
// Load the graphic into a new draw document as xDocument
// using a named filter
Object desktop = xMCF.createInstanceWithContext(
"com.sun.star.frame.Desktop", xComponentContext);
XComponentLoader xComponentLoader = (XComponentLoader)
UnoRuntime.queryInterface(XComponentLoader.class, desktop);
PropertyValue[] fileProps = new PropertyValue[3];
fileProps[0] = new PropertyValue();
fileProps[0].Name = "FilterName";
fileProps[0].Value = importFilter.get(sSourceMime);
fileProps[1] = new PropertyValue();
fileProps[1].Name = "InputStream";
fileProps[1].Value = new ByteArrayToXInputStreamAdapter(source);
fileProps[2] = new PropertyValue();
fileProps[2].Name = "Hidden";
fileProps[2].Value = new Boolean(true);
XComponent xDocument = xComponentLoader.loadComponentFromURL(
"private:stream", "_blank", 0, fileProps);
// Get the first draw page as xDrawPage
XDrawPagesSupplier xDrawPagesSupplier = (XDrawPagesSupplier)
UnoRuntime.queryInterface(XDrawPagesSupplier.class, xDocument);
XDrawPages xDrawPages = xDrawPagesSupplier.getDrawPages();
Object drawPage = xDrawPages.getByIndex(0);
XDrawPage xDrawPage = (XDrawPage) UnoRuntime.queryInterface(
XDrawPage.class, drawPage);
// Get the shape as xShape
Object shape = xDrawPage.getByIndex(0);
XShape xShape = (XShape) UnoRuntime.queryInterface(XShape.class, shape);
// Move the shape to upper left corner of the page
Point position = new Point();
position.X = 0;
position.Y = 0;
xShape.setPosition(position);
// Adjust the page size and margin to the size of the graphic
XPropertySet xPageProps = (XPropertySet) UnoRuntime.queryInterface(
XPropertySet.class, xDrawPage);
Size size = xShape.getSize();
xPageProps.setPropertyValue("Width", new Integer(size.Width));
xPageProps.setPropertyValue("Height", new Integer(size.Height));
xPageProps.setPropertyValue("BorderTop", new Integer(0));
xPageProps.setPropertyValue("BorderBottom", new Integer(0));
xPageProps.setPropertyValue("BorderLeft", new Integer(0));
xPageProps.setPropertyValue("BorderRight", new Integer(0));
// Export the draw document (xDocument)
refreshDocument(xDocument);
XOutputStreamToByteArrayAdapter outputStream = new XOutputStreamToByteArrayAdapter();
PropertyValue[] exportProps = new PropertyValue[3];
exportProps[0] = new PropertyValue();
exportProps[0].Name = "FilterName";
exportProps[0].Value = exportFilter.get(sTargetMime);
exportProps[1] = new PropertyValue();
exportProps[1].Name = "OutputStream";
exportProps[1].Value = outputStream;
exportProps[2] = new PropertyValue();
exportProps[2].Name = "Overwrite";
exportProps[2].Value = new Boolean(true);
XStorable xStore = (XStorable) UnoRuntime.queryInterface (
XStorable.class, xDocument);
xStore.storeToURL ("private:stream", exportProps);
outputStream.closeOutput();
byte[] result = outputStream.getBuffer();
xDocument.dispose();
if (MIMETypes.EPS.equals(sTargetMime)) {
return epsCleaner.cleanEps(result);
}
else {
return result;
}
}
catch (com.sun.star.beans.PropertyVetoException e) {
}
catch (com.sun.star.beans.UnknownPropertyException e) {
}
catch (com.sun.star.io.IOException e) {
}
catch (com.sun.star.lang.IllegalArgumentException e) {
}
catch (com.sun.star.lang.IndexOutOfBoundsException e) {
}
catch (com.sun.star.lang.WrappedTargetException e) {
}
catch (com.sun.star.uno.Exception e) {
}
// Conversion failed, for whatever reason
return null;
}
protected void refreshDocument(XComponent document) {
XRefreshable refreshable = (XRefreshable) UnoRuntime.queryInterface(XRefreshable.class, document);
if (refreshable != null) {
refreshable.refresh();
}
}
/* Dim SelSize As New com.sun.star.awt.Size
SelSize = oGraphic.Size
oDrawGraphic.GraphicURL = oGraphic.GraphicURL
oDrawGraphic.Size = SelSize
oDrawPage.add(oDrawGraphic)
oDrawGraphic.GraphicCrop = oGraphic.GraphicCrop
oDrawPage.Width = oGraphic.Size.Width
oDrawPage.Height = oGraphic.Size.Height
Dim aFilterData (1) As new com.sun.star.beans.PropertyValue
aFilterData(0).Name = "PixelWidth" '
aFilterData(0).Value = oDrawPage.Width/100 * iPixels / 25.40
aFilterData(1).Name = "PixelHeight"
aFilterData(1).Value = oDrawPage.Height/100 * iPixels / 25.40
Export( oDrawPage, sURLImageResized , aFilterData() )
On error resume Next
oDrawDoc.Close(True)
On error goto 0
SUB Export( xObject, sFileUrl As String, aFilterData )
Dim xExporter As Object
xExporter = createUnoService( "com.sun.star.drawing.GraphicExportFilter" )
xExporter.SetSourceDocument( xObject )
Dim aArgs (2) As new com.sun.star.beans.PropertyValue
'sFileURL = ConvertToURL(sFileURL)
aArgs(0).Name = "FilterName"
aArgs(0).Value = "jpg"
aArgs(1).Name = "URL"
aArgs(1).Value = sFileURL
'print sFileURL
aArgs(2).Name = "FilterData"
aArgs(2).Value = aFilterData
xExporter.filter( aArgs() )
END SUB*/
}

View file

@ -0,0 +1,46 @@
/************************************************************************
*
* Messages.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-05-28)
*
*/
package org.openoffice.da.comp.w2lcommon.filter;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
public class Messages {
private static final String BUNDLE_NAME = "org.openoffice.da.comp.w2lcommon.filter.messages"; //$NON-NLS-1$
private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
.getBundle(BUNDLE_NAME);
private Messages() {
}
public static String getString(String key) {
try {
return RESOURCE_BUNDLE.getString(key);
} catch (MissingResourceException e) {
return '!' + key + '!';
}
}
}

View file

@ -0,0 +1,542 @@
/************************************************************************
*
* OptionsDialogBase.java
*
* Copyright: 2002-2014 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.4 (2014-11-01)
*
*/
package org.openoffice.da.comp.w2lcommon.filter;
import java.util.HashSet;
import com.sun.star.awt.XDialogEventHandler;
import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.XPropertyAccess;
import com.sun.star.beans.XPropertySet;
import com.sun.star.container.XNameAccess;
import com.sun.star.document.XDocumentPropertiesSupplier;
import com.sun.star.frame.XDesktop;
import com.sun.star.lang.XComponent;
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.ui.dialogs.XExecutableDialog;
import com.sun.star.uno.Type;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.util.XChangesBatch;
import org.openoffice.da.comp.w2lcommon.helper.DialogBase;
import org.openoffice.da.comp.w2lcommon.helper.MacroExpander;
import org.openoffice.da.comp.w2lcommon.helper.PropertyHelper;
import org.openoffice.da.comp.w2lcommon.helper.XPropertySetHelper;
/** This class provides an abstract uno component which implements a filter ui
*/
public abstract class OptionsDialogBase extends DialogBase implements
XPropertyAccess { // Filter ui requires XExecutableDialog + XPropertyAccess
//////////////////////////////////////////////////////////////////////////
// The subclass must override the following; and override the
// implementation of XDialogEventHandler if needed
/** Load settings from the registry to the dialog
* The subclass must implement this
*/
protected abstract void loadSettings(XPropertySet xRegistryProps);
/** Save settings from the dialog to the registry and create FilterData
* The subclass must implement this
*/
protected abstract void saveSettings(XPropertySet xRegistryProps, PropertyHelper filterData);
/** Return the name of the library containing the dialog
*/
public abstract String getDialogLibraryName();
/** Return the name of the dialog within the library
*/
public abstract String getDialogName();
/** Return the path to the options in the registry */
public abstract String getRegistryPath();
/** Create a new OptionsDialogBase */
public OptionsDialogBase(XComponentContext xContext) {
super(xContext);
this.xMSF = null; // must be set properly by subclass
mediaProps = null;
sConfigNames = null;
lockedOptions = new HashSet<String>();
}
//////////////////////////////////////////////////////////////////////////
// Implement some methods required by DialogBase
/** Initialize the dialog (eg. with settings from the registry)
*/
public void initialize() {
try {
// Prepare registry view
Object view = getRegistryView(false);
XPropertySet xProps = (XPropertySet)
UnoRuntime.queryInterface(XPropertySet.class,view);
// Load settings using method from subclass
loadSettings(xProps);
// Dispose the registry view
disposeRegistryView(view);
}
catch (com.sun.star.uno.Exception e) {
// Failed to get registry view
}
}
/** Finalize the dialog after execution (eg. save settings to the registry)
*/
public void endDialog() {
try {
// Prepare registry view
Object rwview = getRegistryView(true);
XPropertySet xProps = (XPropertySet)
UnoRuntime.queryInterface(XPropertySet.class,rwview);
// Save settings and create FilterData using method from subclass
PropertyHelper filterData = new PropertyHelper();
saveSettings(xProps, filterData);
// Commit registry changes
XChangesBatch xUpdateContext = (XChangesBatch)
UnoRuntime.queryInterface(XChangesBatch.class,rwview);
try {
xUpdateContext.commitChanges();
}
catch (Exception e) {
// ignore
}
// Dispose the registry view
disposeRegistryView(rwview);
// Update the media properties with the FilterData
PropertyHelper helper = new PropertyHelper(mediaProps);
helper.put("FilterData",filterData.toArray());
mediaProps = helper.toArray();
}
catch (com.sun.star.uno.Exception e) {
// Failed to get registry view
}
}
//////////////////////////////////////////////////////////////////////////
// Some private global variables
// The service factory
protected XMultiServiceFactory xMSF;
// The media properties (set/get via XPropertyAccess implementation)
private PropertyValue[] mediaProps;
// Configuration names (stored during execution of dialog)
private String[] sConfigNames;
// Set of locked controls
private HashSet<String> lockedOptions;
//////////////////////////////////////////////////////////////////////////
// Some private utility methods
// Get the template name from the document with ui focus
private String getTemplateName() {
try {
// Get current component
Object desktop = xContext.getServiceManager()
.createInstanceWithContext("com.sun.star.frame.Desktop",xContext);
XDesktop xDesktop = (XDesktop) UnoRuntime.queryInterface(XDesktop.class,desktop);
XComponent xComponent = xDesktop.getCurrentComponent();
// Get the document info property set
XDocumentPropertiesSupplier xDocPropsSuppl =
UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, xComponent);
return xDocPropsSuppl.getDocumentProperties().getTemplateName();
}
catch (Exception e) {
return "";
}
}
// Get a view of the options root in the registry
private Object getRegistryView(boolean bUpdate)
throws com.sun.star.uno.Exception {
Object provider = xMSF.createInstance(
"com.sun.star.configuration.ConfigurationProvider");
XMultiServiceFactory xProvider = (XMultiServiceFactory)
UnoRuntime.queryInterface(XMultiServiceFactory.class,provider);
PropertyValue[] args = new PropertyValue[1];
args[0] = new PropertyValue();
args[0].Name = "nodepath";
args[0].Value = getRegistryPath();
String sServiceName = bUpdate ?
"com.sun.star.configuration.ConfigurationUpdateAccess" :
"com.sun.star.configuration.ConfigurationAccess";
Object view = xProvider.createInstanceWithArguments(sServiceName,args);
return view;
}
// Dispose a previously obtained registry view
private void disposeRegistryView(Object view) {
XComponent xComponent = (XComponent)
UnoRuntime.queryInterface(XComponent.class,view);
xComponent.dispose();
}
//////////////////////////////////////////////////////////////////////////
// Implement uno interfaces
// Override getTypes() from the interface XTypeProvider
public Type[] getTypes() {
Type[] typeReturn = {};
try {
typeReturn = new Type[] {
new Type( XServiceName.class ),
new Type( XServiceInfo.class ),
new Type( XTypeProvider.class ),
new Type( XExecutableDialog.class ),
new Type( XPropertyAccess.class ),
new Type( XDialogEventHandler.class ) };
} catch(Exception exception) {
}
return typeReturn;
}
// Implement the interface XPropertyAccess
public PropertyValue[] getPropertyValues() {
return mediaProps;
}
public void setPropertyValues(PropertyValue[] props) {
mediaProps = props;
}
//////////////////////////////////////////////////////////////////////////
// Various utility methods to be used by the sublasses
// Helpers to load and save settings
protected void updateLockedOptions() {
lockedOptions.clear();
short nItem = getListBoxSelectedItem("Config");
int nStdConfigs = getListBoxStringItemList("Config").length - sConfigNames.length;
if (nItem>=nStdConfigs) {
// Get current configuration name
String sName = sConfigNames[nItem-nStdConfigs];
try {
// Prepare registry view
Object view = getRegistryView(false);
XPropertySet xProps = (XPropertySet)
UnoRuntime.queryInterface(XPropertySet.class,view);
// Get the available configurations
Object configurations = XPropertySetHelper.getPropertyValue(xProps,"Configurations");
XNameAccess xConfigurations = (XNameAccess)
UnoRuntime.queryInterface(XNameAccess.class,configurations);
// Get the LockedOptions node from the desired configuration
String sLockedOptions = "";
Object config = xConfigurations.getByName(sName);
XPropertySet xCfgProps = (XPropertySet)
UnoRuntime.queryInterface(XPropertySet.class,config);
sLockedOptions = XPropertySetHelper.getPropertyValueAsString(xCfgProps,"LockedOptions");
// Dispose the registry view
disposeRegistryView(view);
// Feed lockedOptions with the comma separated list of options
int nStart = 0;
for (int i=0; i<sLockedOptions.length(); i++) {
if (sLockedOptions.charAt(i)==',') {
lockedOptions.add(sLockedOptions.substring(nStart,i).trim());
nStart = i+1;
}
}
if (nStart<sLockedOptions.length()) {
lockedOptions.add(sLockedOptions.substring(nStart).trim());
}
}
catch (Exception e) {
// no options will be locked...
}
}
}
protected boolean isLocked(String sOptionName) {
return lockedOptions.contains(sOptionName);
}
// Configuration
protected void loadConfig(XPropertySet xProps) {
// The list box is extended with configurations from the registry
String[] sStdConfigs = getListBoxStringItemList("Config");
int nStdConfigs = sStdConfigs.length;
Object configurations = XPropertySetHelper.getPropertyValue(xProps,"Configurations");
XNameAccess xConfigurations = (XNameAccess)
UnoRuntime.queryInterface(XNameAccess.class,configurations);
sConfigNames = xConfigurations.getElementNames();
int nRegConfigs = sConfigNames.length;
String[] sAllConfigs = new String[nStdConfigs+nRegConfigs];
for (short i=0; i<nStdConfigs; i++) {
sAllConfigs[i] = sStdConfigs[i];
}
for (short i=0; i<nRegConfigs; i++) {
try {
Object config = xConfigurations.getByName(sConfigNames[i]);
XPropertySet xCfgProps = (XPropertySet)
UnoRuntime.queryInterface(XPropertySet.class,config);
sAllConfigs[nStdConfigs+i] = XPropertySetHelper.getPropertyValueAsString(xCfgProps,"DisplayName");
}
catch (Exception e) {
sAllConfigs[nStdConfigs+i] = "";
}
}
setListBoxStringItemList("Config",sAllConfigs);
if (nStdConfigs+nRegConfigs<=12) {
setListBoxLineCount("Config",(short) (nStdConfigs+nRegConfigs));
}
else {
setListBoxLineCount("Config",(short) 12);
}
// Select item based on template name
String sTheTemplateName = getTemplateName();
Object templates = XPropertySetHelper.getPropertyValue(xProps,"Templates");
XNameAccess xTemplates = (XNameAccess)
UnoRuntime.queryInterface(XNameAccess.class,templates);
String[] sTemplateNames = xTemplates.getElementNames();
for (int i=0; i<sTemplateNames.length; i++) {
try {
Object template = xTemplates.getByName(sTemplateNames[i]);
XPropertySet xTplProps = (XPropertySet)
UnoRuntime.queryInterface(XPropertySet.class,template);
String sTemplateName = XPropertySetHelper.getPropertyValueAsString(xTplProps,"TemplateName");
if (sTemplateName.equals(sTheTemplateName)) {
String sConfigName = XPropertySetHelper.getPropertyValueAsString(xTplProps,"ConfigName");
for (short j=0; j<nRegConfigs; j++) {
if (sConfigNames[j].equals(sConfigName)) {
setListBoxSelectedItem("Config",(short) (nStdConfigs+j));
return;
}
}
}
}
catch (Exception e) {
// ignore
}
}
// Select item based on value stored in registry
short nConfig = XPropertySetHelper.getPropertyValueAsShort(xProps,"Config");
if (nConfig<nStdConfigs) {
setListBoxSelectedItem("Config",nConfig);
}
else { // Registry configurations are stored by name
String sConfigName = XPropertySetHelper.getPropertyValueAsString(xProps,"ConfigName");
for (short i=0; i<nRegConfigs; i++) {
if (sConfigNames[i].equals(sConfigName)) {
setListBoxSelectedItem("Config",(short) (nStdConfigs+i));
}
}
}
}
protected short saveConfig(XPropertySet xProps, PropertyHelper filterData) {
// The Config list box is common for all dialogs
Object configurations = XPropertySetHelper.getPropertyValue(xProps,"Configurations");
XNameAccess xNameAccess = (XNameAccess)
UnoRuntime.queryInterface(XNameAccess.class,configurations);
short nConfig = getListBoxSelectedItem("Config");
int nStdConfigs = getListBoxStringItemList("Config").length - sConfigNames.length;
if (nConfig>=nStdConfigs) { // only handle registry configurations
int i = nConfig-nStdConfigs;
XPropertySetHelper.setPropertyValue(xProps,"ConfigName",sConfigNames[i]);
try {
Object config = xNameAccess.getByName(sConfigNames[i]);
XPropertySet xCfgProps = (XPropertySet)
UnoRuntime.queryInterface(XPropertySet.class,config);
MacroExpander expander = new MacroExpander(xContext);
filterData.put("ConfigURL",expander.expandMacros(XPropertySetHelper.getPropertyValueAsString(xCfgProps,"ConfigURL")));
filterData.put("TemplateURL",expander.expandMacros(XPropertySetHelper.getPropertyValueAsString(xCfgProps,"TargetTemplateURL")));
filterData.put("StyleSheetURL",expander.expandMacros(XPropertySetHelper.getPropertyValueAsString(xCfgProps,"StyleSheetURL")));
// The resources are provided as a set
Object resources = XPropertySetHelper.getPropertyValue(xCfgProps,"Resources");
XNameAccess xResourceNameAccess = (XNameAccess) UnoRuntime.queryInterface(XNameAccess.class,resources);
if (xResourceNameAccess!=null) {
StringBuilder buf = new StringBuilder();
String[] sResourceNames = xResourceNameAccess.getElementNames();
for (String sName : sResourceNames) {
Object resource = xResourceNameAccess.getByName(sName);
XPropertySet xResourceProps = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class,resource);
String sURL = expander.expandMacros(XPropertySetHelper.getPropertyValueAsString(xResourceProps,"URL"));
String sFileName = expander.expandMacros(XPropertySetHelper.getPropertyValueAsString(xResourceProps,"FileName"));
String sMediaType = expander.expandMacros(XPropertySetHelper.getPropertyValueAsString(xResourceProps,"MediaType"));
if (buf.length()>0) { buf.append(';'); }
buf.append(sURL).append("::").append(sFileName).append("::").append(sMediaType);
}
filterData.put("Resources",buf.toString());
}
}
catch (Exception e) {
}
}
else { // Standard configurations have no name
XPropertySetHelper.setPropertyValue(xProps,"ConfigName","");
}
XPropertySetHelper.setPropertyValue(xProps,"Config",nConfig);
return nConfig;
}
// Check box option (boolean)
protected boolean loadCheckBoxOption(XPropertySet xProps, String sName) {
boolean bValue = XPropertySetHelper.getPropertyValueAsBoolean(xProps,sName);
setCheckBoxStateAsBoolean(sName, bValue);
return bValue;
}
protected boolean saveCheckBoxOption(XPropertySet xProps, String sName) {
boolean bValue = getCheckBoxStateAsBoolean(sName);
XPropertySetHelper.setPropertyValue(xProps, sName, bValue);
return bValue;
}
protected boolean saveCheckBoxOption(XPropertySet xProps, PropertyHelper filterData,
String sName, String sOptionName) {
boolean bValue = saveCheckBoxOption(xProps, sName);
if (!isLocked(sOptionName)) {
filterData.put(sOptionName, Boolean.toString(bValue));
}
return bValue;
}
// List box option
protected short loadListBoxOption(XPropertySet xProps, String sName) {
short nValue = XPropertySetHelper.getPropertyValueAsShort(xProps, sName);
setListBoxSelectedItem(sName ,nValue);
return nValue;
}
protected short saveListBoxOption(XPropertySet xProps, String sName) {
short nValue = getListBoxSelectedItem(sName);
XPropertySetHelper.setPropertyValue(xProps, sName, nValue);
return nValue;
}
protected short saveListBoxOption(XPropertySet xProps, PropertyHelper filterData,
String sName, String sOptionName, String[] sValues) {
short nValue = saveListBoxOption(xProps, sName);
if (!isLocked(sOptionName) && (nValue>=0) && (nValue<sValues.length)) {
filterData.put(sOptionName, sValues[nValue]);
}
return nValue;
}
// Combo box option
protected String loadComboBoxOption(XPropertySet xProps, String sName) {
String sValue = XPropertySetHelper.getPropertyValueAsString(xProps, sName);
setComboBoxText(sName ,sValue);
return sValue;
}
protected String saveComboBoxOption(XPropertySet xProps, String sName) {
String sValue = getComboBoxText(sName);
XPropertySetHelper.setPropertyValue(xProps, sName, sValue);
return sValue;
}
protected String saveComboBoxOption(XPropertySet xProps, PropertyHelper filterData,
String sName, String sOptionName) {
String sValue = saveComboBoxOption(xProps, sName);
if (!isLocked(sOptionName)) {
filterData.put(sOptionName, sValue);
}
return sValue;
}
// Text Field option
protected String loadTextFieldOption(XPropertySet xProps, String sName) {
String sValue = XPropertySetHelper.getPropertyValueAsString(xProps, sName);
setTextFieldText(sName ,sValue);
return sValue;
}
protected String saveTextFieldOption(XPropertySet xProps, String sName) {
String sValue = getTextFieldText(sName);
XPropertySetHelper.setPropertyValue(xProps, sName, sValue);
return sValue;
}
protected String saveTextFieldOption(XPropertySet xProps, PropertyHelper filterData,
String sName, String sOptionName) {
String sValue = saveTextFieldOption(xProps, sName);
if (!isLocked(sOptionName)) {
filterData.put(sOptionName, sValue);
}
return sValue;
}
// Numeric option
protected int loadNumericOption(XPropertySet xProps, String sName) {
int nValue = XPropertySetHelper.getPropertyValueAsInteger(xProps, sName);
setNumericFieldValue(sName, nValue);
return nValue;
}
protected int saveNumericOption(XPropertySet xProps, String sName) {
int nValue = getNumericFieldValue(sName);
XPropertySetHelper.setPropertyValue(xProps, sName, nValue);
return nValue;
}
protected int saveNumericOptionAsPercentage(XPropertySet xProps,
PropertyHelper filterData, String sName, String sOptionName) {
int nValue = saveNumericOption(xProps, sName);
if (!isLocked(sOptionName)) {
filterData.put(sOptionName,Integer.toString(nValue)+"%");
}
return nValue;
}
}

View file

@ -0,0 +1,264 @@
/************************************************************************
*
* UNOConverter.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-05-06)
*
*/
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), FilterData (optional)
* and FilterOptions (optional, alternative to FilterData)
*/
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.writer2xhtml.epub3","epub3");
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;
Object filterOptions = 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;
}
if (pValue[i].Name.compareTo("FilterOptions")==0) {
filterOptions = 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);
}
else if (filterOptions!=null) {
FilterDataParser fdp = new FilterDataParser(xComponentContext);
fdp.applyFilterOptions(filterOptions,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

@ -0,0 +1,342 @@
/************************************************************************
*
* UNOPublisher.java
*
* Copyright: 2002-2018 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2018-03-06)
*
*/
package org.openoffice.da.comp.w2lcommon.filter;
import java.io.IOException;
import java.util.regex.Pattern;
import org.openoffice.da.comp.w2lcommon.helper.MessageBox;
import writer2latex.util.Misc;
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.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;
/** This class converts an open office document to another format
*/
public class UNOPublisher {
public enum TargetFormat { xhtml, xhtml11, xhtml_mathml, html5, epub, epub3, latex };
private String sAppName;
protected XComponentContext xContext;
protected XFrame xFrame;
private XModel xModel = null;
private PropertyValue[] mediaProps = null;
/** Create a new <code>UNOPublisher</code> based on a loaded office document
*
* @param xContext the component context from which new UNO services are instantiated
* @param xFrame the current frame
* @param sAppName the name of the application using the <code>UNOPublisher</code>
*/
public UNOPublisher(XComponentContext xContext, XFrame xFrame, String sAppName) {
this.xContext = xContext;
this.xFrame = xFrame;
this.sAppName = sAppName;
// Get the model for the document from the frame
XController xController = xFrame.getController();
if (xController!=null) {
xModel = xController.getModel();
}
}
/** Publish the document associated with this <code>UNOPublisher</code>. This involves five steps:
* (1) Check that the document is saved in the local file system.
* (2) Display the options dialog.
* (3) Save the document (if the modified flag is true).
* (4) Convert the document.
* (5) Post process the document, e.g. displaying the result
*
* @param format the target format
* @return true if the publishing was successful
*/
public boolean publish(TargetFormat format) {
if (documentSaved() && updateMediaProperties(format)) {
// Create a (somewhat coarse grained) status indicator/progress bar
XStatusIndicatorFactory xFactory = (com.sun.star.task.XStatusIndicatorFactory)
UnoRuntime.queryInterface(com.sun.star.task.XStatusIndicatorFactory.class, xFrame);
XStatusIndicator xStatus = xFactory.createStatusIndicator();
xStatus.start(sAppName,10);
xStatus.setValue(1); // At least we have started, that's 10% :-)
try {
// Save document if required
saveDocument();
xStatus.setValue(4); // Document saved, that's 40%
// Convert to desired format
UNOConverter converter = new UNOConverter(mediaProps, xContext);
// Initialize the file access (to read the office document)
XSimpleFileAccess2 sfa2 = null;
try {
Object sfaObject = xContext.getServiceManager().createInstanceWithContext(
"com.sun.star.ucb.SimpleFileAccess", xContext); //$NON-NLS-1$
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 e) {
xStatus.end();
MessageBox msgBox = new MessageBox(xContext, xFrame);
msgBox.showMessage(sAppName,Messages.getString("UNOPublisher.failexport")); //$NON-NLS-1$
return false;
}
catch (com.sun.star.uno.Exception e) {
xStatus.end();
MessageBox msgBox = new MessageBox(xContext, xFrame);
msgBox.showMessage(sAppName,Messages.getString("UNOPublisher.failexport")); //$NON-NLS-1$
return false;
}
xStatus.setValue(7); // Document is converted, that's 70%
postProcess(getTargetURL(format),format);
xStatus.setValue(10); // Export is finished (The user will usually not see this...)
xStatus.end();
return true;
}
return false;
}
/** Filter the file name to avoid unwanted characters
*
* @param sFileName the original file name
* @return the filtered file name
*/
protected String filterFileName(String sFileName) {
return sFileName;
}
/** Post process the media properties after displaying the dialog
*
* @param mediaProps the media properties as set by the dialog
* @return the updated media properties
*/
protected PropertyValue[] postProcessMediaProps(PropertyValue[] mediaProps) {
return mediaProps;
}
/** Post process the document after conversion.
*
* @param sTargetURL URL of the converted document
* @param format the target format
*/
protected void postProcess(String sTargetURL, TargetFormat format) {
}
/** Check that the document is saved in a location, we can use
*
* @return true if everthing is o.k.
*/
public boolean documentSaved() {
String sDocumentUrl = xModel.getURL();
if (sDocumentUrl.length()==0) { // The document has no location
MessageBox msgBox = new MessageBox(xContext, xFrame);
msgBox.showMessage(sAppName,Messages.getString("UNOPublisher.savedocument")); //$NON-NLS-1$
return false;
}
else if (!".odt".equals(Misc.getFileExtension(sDocumentUrl)) && !".fodt".equals(Misc.getFileExtension(sDocumentUrl)) && !".ods".equals(Misc.getFileExtension(sDocumentUrl)) && !".fods".equals(Misc.getFileExtension(sDocumentUrl))) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
MessageBox msgBox = new MessageBox(xContext, xFrame);
msgBox.showMessage(sAppName,Messages.getString("UNOPublisher.saveodt")); //$NON-NLS-1$
return false;
}
else if (!sDocumentUrl.startsWith("file:")) { //$NON-NLS-1$
MessageBox msgBox = new MessageBox(xContext, xFrame);
msgBox.showMessage(sAppName,Messages.getString("UNOPublisher.savefilesystem")); //$NON-NLS-1$
return false;
}
else if (System.getProperty("os.name").startsWith("Windows")) { //$NON-NLS-1$ //$NON-NLS-2$
// Avoid UNC paths (LaTeX does not like them)
Pattern windowsPattern = Pattern.compile("^file:///[A-Za-z][|:].*"); //$NON-NLS-1$
if (!windowsPattern.matcher(sDocumentUrl).matches()) {
MessageBox msgBox = new MessageBox(xContext, xFrame);
msgBox.showMessage(sAppName,
Messages.getString("UNOPublisher.savedrivename")); //$NON-NLS-1$
return false;
}
}
return true;
}
private boolean saveDocument() {
XModifiable xModifiable = (XModifiable) UnoRuntime.queryInterface(XModifiable.class, xModel);
if (xModifiable.isModified()) { // The document 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;
}
}
return true;
}
// Some utility methods
/** Get the target path (or null if the document is not saved)
*
* @return the path
*/
public String getTargetPath() {
if (xModel.getURL().length()>0) {
String sBaseURL = Misc.removeExtension(xModel.getURL());
return Misc.getPath(sBaseURL);
}
return null;
}
/** Get the target file name (or null if the document is not saved)
*
* @return the file name
*/
public String getTargetFileName() {
if (xModel.getURL().length()>0) {
String sBaseURL = Misc.removeExtension(xModel.getURL());
return filterFileName(Misc.getFileName(sBaseURL));
}
return null;
}
protected String getTargetURL(TargetFormat format) {
return getTargetPath()+getTargetFileName()+getTargetExtension(format);
}
private void prepareMediaProperties(TargetFormat format) {
// Create inital media properties
mediaProps = new PropertyValue[2];
mediaProps[0] = new PropertyValue();
mediaProps[0].Name = "FilterName"; //$NON-NLS-1$
mediaProps[0].Value = getFilterName(format);
mediaProps[1] = new PropertyValue();
mediaProps[1].Name = "URL"; //$NON-NLS-1$
mediaProps[1].Value = getTargetURL(format);
}
private boolean updateMediaProperties(TargetFormat format) {
prepareMediaProperties(format);
String sDialogName = xModel.getURL().endsWith(".odt") || xModel.getURL().endsWith(".fodt") ? //$NON-NLS-1$ //$NON-NLS-2$
getDialogName(format) : getDialogNameCalc(format);
if (sDialogName!=null) {
try {
// Display options dialog
Object dialog = xContext.getServiceManager()
.createInstanceWithContext(sDialogName, 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 = postProcessMediaProps(xPropertyAccess.getPropertyValues());
return true;
}
}
catch (com.sun.star.beans.UnknownPropertyException e) {
// setPropertyValues will not fail..
}
catch (com.sun.star.uno.Exception e) {
// getServiceManager will not fail..
}
}
// No dialog exists, or the dialog was cancelled
mediaProps = null;
return false;
}
private static String getTargetExtension(TargetFormat format) {
switch (format) {
case xhtml: return ".html"; //$NON-NLS-1$
case xhtml11: return ".xhtml"; //$NON-NLS-1$
case xhtml_mathml: return ".xhtml"; //$NON-NLS-1$
case html5: return ".html"; //$NON-NLS-1$
case epub: return ".epub"; //$NON-NLS-1$
case epub3: return ".epub"; //$NON-NLS-1$
case latex: return ".tex"; //$NON-NLS-1$
default: return ""; //$NON-NLS-1$
}
}
private static String getDialogName(TargetFormat format) {
switch (format) {
case xhtml:
case xhtml11: return "org.openoffice.da.comp.writer2xhtml.XhtmlOptionsDialog"; //$NON-NLS-1$
case xhtml_mathml:
case html5: return "org.openoffice.da.comp.writer2xhtml.XhtmlOptionsDialogMath"; //$NON-NLS-1$
case epub: return "org.openoffice.da.comp.writer2xhtml.EpubOptionsDialog"; //$NON-NLS-1$
case epub3: return "org.openoffice.da.comp.writer2xhtml.Epub3OptionsDialog"; //$NON-NLS-1$
case latex: return "org.openoffice.da.comp.writer2latex.LaTeXOptionsDialog"; //$NON-NLS-1$
default: return null;
}
}
private static String getDialogNameCalc(TargetFormat format) {
switch (format) {
case xhtml:
case xhtml11:
case xhtml_mathml:
case html5: return "org.openoffice.da.comp.writer2xhtml.XhtmlOptionsDialogCalc"; //$NON-NLS-1$
case epub:
case epub3:
case latex:
default: return null;
}
}
private static String getFilterName(TargetFormat format) {
switch (format) {
case xhtml: return "org.openoffice.da.writer2xhtml"; //$NON-NLS-1$
case xhtml11: return "org.openoffice.da.writer2xhtml11"; //$NON-NLS-1$
case xhtml_mathml: return "org.openoffice.da.writer2xhtml.mathml"; //$NON-NLS-1$
case html5: return "org.openoffice.da.writer2xhtml5"; //$NON-NLS-1$
case epub: return "org.openoffice.da.writer2xhtml.epub"; //$NON-NLS-1$
case epub3: return "org.openoffice.da.writer2xhtml.epub3"; //$NON-NLS-1$
case latex: return "org.openoffice.da.writer2latex"; //$NON-NLS-1$
default: return ""; //$NON-NLS-1$
}
}
}

View file

@ -0,0 +1,5 @@
UNOPublisher.failexport=Error: Failed to export document
UNOPublisher.savedocument=Please save the document first
UNOPublisher.saveodt=Please save the document in OpenDocument format (.odt)
UNOPublisher.savefilesystem=Please save the document in the local file system
UNOPublisher.savedrivename=Please save the document on a location with a drive name

View file

@ -0,0 +1,5 @@
UNOPublisher.failexport=Fejl: Kunne ikke eksportere dokumentet
UNOPublisher.savedocument=Gem dokumentet først
UNOPublisher.saveodt=Gem dokumentet i OpenDocument-format (.odt)
UNOPublisher.savefilesystem=Gem dokumentet i det lokale filsystem
UNOPublisher.savedrivename=Gem dokumentet et sted med et drevbogstav

View file

@ -0,0 +1,352 @@
/************************************************************************
*
* DialogAccess.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-04-15)
*
*/
package org.openoffice.da.comp.w2lcommon.helper;
import com.sun.star.awt.XControl;
import com.sun.star.awt.XControlContainer;
import com.sun.star.awt.XControlModel;
import com.sun.star.awt.XDialog;
import com.sun.star.beans.XPropertySet;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.util.Date;
/** This class provides some convenient methods to access a uno dialog
*/
public class DialogAccess {
/** The XDialog containing the controls. */
private XDialog xDialog = null;
// State of a checkbox
public static final short CHECKBOX_NOT_CHECKED = 0;
public static final short CHECKBOX_CHECKED = 1;
public static final short CHECKBOX_DONT_KNOW = 2;
public DialogAccess(XDialog xDialog) {
this.xDialog = xDialog;
}
protected void setDialog(XDialog xDialog) {
this.xDialog = xDialog;
}
protected XDialog getDialog() {
return this.xDialog;
}
//////////////////////////////////////////////////////////////////////////
// Helpers to access controls in the dialog (to be used by the subclass)
// Note: The helpers fail silently if an exception occurs. Could query the
// the ClassId property for the control type and check that the property
// exists to ensure a correct behaviour in all cases, but as long as the
// helpers are used correctly, this doesn't really matter.
// Get the properties of a named control in the dialog
public XPropertySet getControlProperties(String sControlName) {
XControlContainer xContainer = (XControlContainer)
UnoRuntime.queryInterface(XControlContainer.class, xDialog);
XControl xControl = xContainer.getControl(sControlName);
XControlModel xModel = xControl.getModel();
XPropertySet xPropertySet = (XPropertySet)
UnoRuntime.queryInterface(XPropertySet.class, xModel);
return xPropertySet;
}
public boolean getControlEnabled(String sControlName) {
XPropertySet xPropertySet = getControlProperties(sControlName);
try {
return ((Boolean) xPropertySet.getPropertyValue("Enabled")).booleanValue();
}
catch (Exception e) {
// Will fail if the control does not exist
return false;
}
}
public void setControlEnabled(String sControlName, boolean bEnabled) {
XPropertySet xPropertySet = getControlProperties(sControlName);
try {
xPropertySet.setPropertyValue("Enabled", new Boolean(bEnabled));
}
catch (Exception e) {
// Will fail if the control does not exist
}
}
public short getCheckBoxState(String sControlName) {
XPropertySet xPropertySet = getControlProperties(sControlName);
try {
return ((Short) xPropertySet.getPropertyValue("State")).shortValue();
}
catch (Exception e) {
// Will fail if the control does not exist or is not a checkbox
return CHECKBOX_DONT_KNOW;
}
}
public boolean getCheckBoxStateAsBoolean(String sControlName) {
return getCheckBoxState(sControlName)==CHECKBOX_CHECKED;
}
public void setCheckBoxState(String sControlName, short nState) {
XPropertySet xPropertySet = getControlProperties(sControlName);
try {
xPropertySet.setPropertyValue("State",new Short(nState));
}
catch (Exception e) {
// will fail if the control does not exist or is not a checkbox or
// nState has an illegal value
}
}
public void setCheckBoxStateAsBoolean(String sControlName, boolean bChecked) {
setCheckBoxState(sControlName,bChecked ? CHECKBOX_CHECKED : CHECKBOX_NOT_CHECKED);
}
public String[] getListBoxStringItemList(String sControlName) {
XPropertySet xPropertySet = getControlProperties(sControlName);
try {
return (String[]) xPropertySet.getPropertyValue("StringItemList");
}
catch (Exception e) {
// Will fail if the control does not exist or is not a list box
return new String[0];
}
}
public void setListBoxStringItemList(String sControlName, String[] items) {
XPropertySet xPropertySet = getControlProperties(sControlName);
try {
xPropertySet.setPropertyValue("StringItemList",items);
}
catch (Exception e) {
// Will fail if the control does not exist or is not a list box
}
}
public short getListBoxSelectedItem(String sControlName) {
// Returns the first selected element in case of a multiselection
XPropertySet xPropertySet = getControlProperties(sControlName);
try {
short[] selection = (short[]) xPropertySet.getPropertyValue("SelectedItems");
return selection[0];
}
catch (Exception e) {
// Will fail if the control does not exist or is not a list box
return -1;
}
}
public void setListBoxSelectedItem(String sControlName, short nIndex) {
XPropertySet xPropertySet = getControlProperties(sControlName);
try {
short[] selection = new short[1];
selection[0] = nIndex;
xPropertySet.setPropertyValue("SelectedItems",selection);
}
catch (Exception e) {
// Will fail if the control does not exist or is not a list box or
// nIndex is an illegal value
}
}
public short getListBoxLineCount(String sControlName) {
XPropertySet xPropertySet = getControlProperties(sControlName);
try {
return ((Short) xPropertySet.getPropertyValue("LineCount")).shortValue();
}
catch (Exception e) {
// Will fail if the control does not exist or is not a list box
return 0;
}
}
public void setListBoxLineCount(String sControlName, short nLineCount) {
XPropertySet xPropertySet = getControlProperties(sControlName);
try {
xPropertySet.setPropertyValue("LineCount",new Short(nLineCount));
}
catch (Exception e) {
// Will fail if the control does not exist or is not a list box or
// nLineCount is an illegal value
}
}
public String getComboBoxText(String sControlName) {
// Returns the text of a combobox
XPropertySet xPropertySet = getControlProperties(sControlName);
try {
return (String) xPropertySet.getPropertyValue("Text");
}
catch (Exception e) {
// Will fail if the control does not exist or is not a combo
return "";
}
}
public void setComboBoxText(String sControlName, String sText) {
XPropertySet xPropertySet = getControlProperties(sControlName);
try {
xPropertySet.setPropertyValue("Text", sText);
}
catch (Exception e) {
// Will fail if the control does not exist or is not a combo box or
// nText is an illegal value
}
}
public String getLabelText(String sControlName) {
XPropertySet xPropertySet = getControlProperties(sControlName);
try {
return (String) xPropertySet.getPropertyValue("Label");
}
catch (Exception e) {
// Will fail if the control does not exist or is not a label
return "";
}
}
public void setLabelText(String sControlName, String sLabel) {
XPropertySet xPropertySet = getControlProperties(sControlName);
try {
xPropertySet.setPropertyValue("Label",sLabel);
}
catch (Exception e) {
// Will fail if the control does not exist or is not a label
}
}
public String getTextFieldText(String sControlName) {
XPropertySet xPropertySet = getControlProperties(sControlName);
try {
return (String) xPropertySet.getPropertyValue("Text");
}
catch (Exception e) {
// Will fail if the control does not exist or is not a text field
return "";
}
}
public void setTextFieldText(String sControlName, String sText) {
XPropertySet xPropertySet = getControlProperties(sControlName);
try {
xPropertySet.setPropertyValue("Text",sText);
}
catch (Exception e) {
// Will fail if the control does not exist or is not a text field
}
}
public String getFormattedFieldText(String sControlName) {
XPropertySet xPropertySet = getControlProperties(sControlName);
try {
return (String) xPropertySet.getPropertyValue("Text");
}
catch (Exception e) {
// Will fail if the control does not exist or is not a formatted field
return "";
}
}
public void setFormattedFieldText(String sControlName, String sText) {
XPropertySet xPropertySet = getControlProperties(sControlName);
try {
xPropertySet.setPropertyValue("Text",sText);
}
catch (Exception e) {
// Will fail if the control does not exist or is not a formatted field
}
}
public int getDateFieldValue(String sControlName) {
XPropertySet xPropertySet = getControlProperties(sControlName);
try {
Object dateObject = xPropertySet.getPropertyValue("Date");
if (dateObject instanceof Date) {
// Since LO 4.1
Date date = (Date) dateObject;
return 10000*date.Year+100*date.Month+date.Day;
}
else if (dateObject instanceof Integer) {
// AOO and older versions of LO
return ((Integer) dateObject).intValue();
}
else {
// The date field does not have a value
return 0;
}
}
catch (Exception e) {
// Will fail if the control does not exist or is not a date field
return 0;
}
}
public void setDateFieldValue(String sControlName, int nValue) {
XPropertySet xPropertySet = getControlProperties(sControlName);
Date date = new Date();
date.Year = (short) (nValue/10000);
date.Month = (short) ((nValue%10000)/100);
date.Day = (short) (nValue%100);
// TODO: Use reflection to identify the correct type of the property
try {
// Since LO 4.1
xPropertySet.setPropertyValue("Date", date);
} catch (Exception e) {
// AOO and older versions of LO
try {
xPropertySet.setPropertyValue("Date", nValue);
} catch (Exception e1) {
}
}
}
public int getNumericFieldValue(String sControlName) {
XPropertySet xPropertySet = getControlProperties(sControlName);
try {
return ((Double) xPropertySet.getPropertyValue("Value")).intValue();
}
catch (Exception e) {
// Will fail if the control does not exist or is not a numeric field
return 0;
}
}
public void setNumericFieldValue(String sControlName, int nValue) {
XPropertySet xPropertySet = getControlProperties(sControlName);
try {
xPropertySet.setPropertyValue("Value",new Double(nValue));
}
catch (Exception e) {
// Will fail if the control does not exist or is not a numeric field
}
}
}

View file

@ -0,0 +1,203 @@
/************************************************************************
*
* DialogBase.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-04-15)
*
*/
package org.openoffice.da.comp.w2lcommon.helper;
import com.sun.star.awt.XDialog;
import com.sun.star.awt.XDialogEventHandler;
import com.sun.star.awt.XDialogProvider2;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.lang.XServiceName;
import com.sun.star.lang.XTypeProvider;
import com.sun.star.ui.dialogs.ExecutableDialogResults;
import com.sun.star.ui.dialogs.XExecutableDialog;
import com.sun.star.uno.Type;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
/** This class provides an abstract uno component which implements a dialog
* from an xml description (using the DialogProvider2 service)
*/
public abstract class DialogBase extends DialogAccess implements
XTypeProvider, XServiceInfo, XServiceName, // Uno component
XExecutableDialog, // Execute the dialog
XDialogEventHandler { // Event handling for dialog
//////////////////////////////////////////////////////////////////////////
// The subclass must override the following; and override the
// implementation of XDialogEventHandler if needed
/** The component will be registered under this name.
* The subclass must override this with a suitable name
*/
public static String __serviceName = "";
/** The component should also have an implementation name.
* The subclass must override this with a suitable name
*/
public static String __implementationName = "";
/** Return the name of the library containing the dialog
* The subclass must override this to provide the name of the library
*/
public abstract String getDialogLibraryName();
/** Return the name of the dialog within the library
* The subclass must override this to provide the name of the dialog
*/
public abstract String getDialogName();
/** Initialize the dialog (eg. with settings from the registry)
* The subclass must implement this
*/
protected abstract void initialize();
/** End the dialog after execution (eg. save settings to the registry)
* The subclass must implement this
*/
protected abstract void endDialog();
//////////////////////////////////////////////////////////////////////////
// Some private global variables
// The component context (from constructor)
protected XComponentContext xContext;
// The dialog title (created by XExecutableDialog implementation)
private String sTitle;
//////////////////////////////////////////////////////////////////////////
// The constructor
/** Create a new OptionsDialogBase */
public DialogBase(XComponentContext xContext) {
super(null);
this.xContext = xContext;
sTitle = null;
}
//////////////////////////////////////////////////////////////////////////
// Implement uno interfaces
// Implement the interface XTypeProvider
public Type[] getTypes() {
Type[] typeReturn = {};
try {
typeReturn = new Type[] {
new Type( XServiceName.class ),
new Type( XServiceInfo.class ),
new Type( XTypeProvider.class ),
new Type( XExecutableDialog.class ),
new Type( XDialogEventHandler.class ) };
} catch(Exception exception) {
}
return typeReturn;
}
public byte[] getImplementationId() {
byte[] byteReturn = {};
byteReturn = new String( "" + this.hashCode() ).getBytes();
return( byteReturn );
}
// Implement the interface XServiceName
public String getServiceName() {
return __serviceName;
}
// Implement the interface XServiceInfo
public boolean supportsService(String sServiceName) {
return sServiceName.equals(__serviceName);
}
public String getImplementationName() {
return __implementationName;
}
public String[] getSupportedServiceNames() {
String[] sSupportedServiceNames = { __serviceName };
return sSupportedServiceNames;
}
// Implement the interface XExecutableDialog
public void setTitle(String sTitle) {
this.sTitle = sTitle;
}
public short execute() {
try {
// Create the dialog
XMultiComponentFactory xMCF = xContext.getServiceManager();
Object provider = xMCF.createInstanceWithContext(
"com.sun.star.awt.DialogProvider2", xContext);
XDialogProvider2 xDialogProvider = (XDialogProvider2)
UnoRuntime.queryInterface(XDialogProvider2.class, provider);
String sDialogUrl = "vnd.sun.star.script:"+getDialogLibraryName()+"."
+getDialogName()+"?location=application";
setDialog(xDialogProvider.createDialogWithHandler(sDialogUrl, this));
if (sTitle!=null) { getDialog().setTitle(sTitle); }
// Do initialization using method from subclass
initialize();
// Execute the dialog
short nResult = getDialog().execute();
if (nResult == ExecutableDialogResults.OK) {
// Finalize after execution of dialog using method from subclass
endDialog();
}
getDialog().endExecute();
return nResult;
}
catch (Exception e) {
// continue as if the dialog was executed OK
return ExecutableDialogResults.OK;
}
}
// Implement the interface XDialogEventHandler
public boolean callHandlerMethod(XDialog xDialog, Object event, String sMethod) {
// Do nothing, leaving the responsibility to the subclass
return true;
}
public String[] getSupportedMethodNames() {
// We do not support any method names, subclass should take care of this
return new String[0];
}
}

View file

@ -0,0 +1,92 @@
/************************************************************************
*
* FiledMasterNameProvider.java
*
* Copyright: 2002-2010 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.2 (2010-12-09)
*
*/
package org.openoffice.da.comp.w2lcommon.helper;
import java.util.HashSet;
import java.util.Set;
import com.sun.star.container.XNameAccess;
import com.sun.star.frame.XController;
import com.sun.star.frame.XDesktop;
import com.sun.star.frame.XModel;
import com.sun.star.text.XTextFieldsSupplier;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
/** This class provides access to the names of all field masters in the current document
*/
public class FieldMasterNameProvider {
private String[] fieldMasterNames;
/** Construct a new <code>FieldMasterNameProvider</code>
*
* @param xContext the component context to get the desktop from
*/
public FieldMasterNameProvider(XComponentContext xContext) {
fieldMasterNames = new String[0];
// TODO: This code should be shared (identical with StyleNameProvider...)
// Get the model for the current frame
XModel xModel = null;
try {
Object desktop = xContext.getServiceManager().createInstanceWithContext("com.sun.star.frame.Desktop", xContext);
XDesktop xDesktop = (XDesktop)UnoRuntime.queryInterface(XDesktop.class, desktop);
XController xController = xDesktop.getCurrentFrame().getController();
if (xController!=null) {
xModel = xController.getModel();
}
}
catch (Exception e) {
// do nothing
}
// Get the field masters from the model
if (xModel!=null) {
XTextFieldsSupplier xSupplier = (XTextFieldsSupplier) UnoRuntime.queryInterface(
XTextFieldsSupplier.class, xModel);
if (xSupplier!=null) {
XNameAccess xFieldMasters = xSupplier.getTextFieldMasters();
fieldMasterNames = xFieldMasters.getElementNames();
}
}
}
/** Get the names of all field masters relative to a given prefix
*
* @param sPrefix the prefix to look for, e.g. "com.sun.star.text.fieldmaster.SetExpression."
* @return a read only <code>Set</code> containing all known names with the given prefix, stripped for the prefix
*/
public Set<String> getFieldMasterNames(String sPrefix) {
Set<String> names = new HashSet<String>();
for (String sName : fieldMasterNames) {
if (sName.startsWith(sPrefix)) {
names.add(sName.substring(sPrefix.length()));
}
}
return names;
}
}

View file

@ -0,0 +1,125 @@
/************************************************************************
*
* FilePicker.java
*
* Copyright: 2002-2014 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.4 (2014-09-24)
*
*/
package org.openoffice.da.comp.w2lcommon.helper;
import com.sun.star.lang.IllegalArgumentException;
import com.sun.star.lang.XComponent;
import com.sun.star.ui.dialogs.ExecutableDialogResults;
import com.sun.star.ui.dialogs.XExecutableDialog;
import com.sun.star.ui.dialogs.XFilePicker;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
public class FilePicker {
private XComponentContext xContext;
// The default directory for the dialog
private String sDirectoryURL;
/** Convenience wrapper class for the UNO file picker service
*
* @param xContext the UNO component context from which the file picker can be created
*/
public FilePicker(XComponentContext xContext) {
this.xContext = xContext;
sDirectoryURL = null;
}
/** Get one or more user selected paths with a file picker
*
* Warning: This does not work on all platforms when using native file pickers
* (but always when using Office file pickers)
*
* @return array containing the path URLs or null if the dialog is canceled
*/
public String[] getPaths() {
return getPaths(true);
}
/** Get a user selected path with a file picker
*
* @return the path URL or null if the dialog is canceled
*/
public String getPath() {
String[] sPaths = getPaths(false);
if (sPaths!=null && sPaths.length>0) {
return sPaths[0];
}
return null;
}
private String[] getPaths(boolean bAllowMultiSelection) {
// Create FilePicker
Object filePicker = null;
try {
// Note: Could be changed for OfficeFilePicker to always use internal file pickers
filePicker = xContext.getServiceManager().createInstanceWithContext("com.sun.star.ui.dialogs.FilePicker", xContext);
}
catch (com.sun.star.uno.Exception e) {
return null;
}
// Get the required interfaces
XFilePicker xFilePicker = (XFilePicker) UnoRuntime.queryInterface(XFilePicker.class, filePicker);
XExecutableDialog xExecutable = (XExecutableDialog) UnoRuntime.queryInterface(XExecutableDialog.class, xFilePicker);
// Configure the file picker
xFilePicker.setMultiSelectionMode(bAllowMultiSelection);
if (sDirectoryURL!=null) {
try {
xFilePicker.setDisplayDirectory(sDirectoryURL);
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
// Get the paths
String[] sPaths = null;
if (xExecutable.execute() == ExecutableDialogResults.OK) {
sDirectoryURL = xFilePicker.getDisplayDirectory();
String[] sPathList = xFilePicker.getFiles();
int nCount = sPathList.length;
if (nCount>1) {
// According to the spec, the first entry is the path and remaining entries are file names
sPaths = new String[nCount-1];
for (int i=1; i<nCount; i++) {
sPaths[i-1]=sPathList[0] + sPathList[i];
}
}
else if (nCount==1) {
sPaths = sPathList;
}
}
// Dispose the file picker
XComponent xComponent = (XComponent) UnoRuntime.queryInterface(XComponent.class, xFilePicker);
xComponent.dispose();
return sPaths;
}
}

View file

@ -0,0 +1,81 @@
/************************************************************************
*
* FolderPicker.java
*
* Copyright: 2002-2010 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.2 (2010-10-11)
*
*/
package org.openoffice.da.comp.w2lcommon.helper;
import com.sun.star.lang.XComponent;
import com.sun.star.ui.dialogs.ExecutableDialogResults;
import com.sun.star.ui.dialogs.XExecutableDialog;
import com.sun.star.ui.dialogs.XFolderPicker;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
public class FolderPicker {
private XComponentContext xContext;
/** Convenience wrapper class for the UNO folder picker service
*
* @param xContext the UNO component context from which the folder picker can be created
*/
public FolderPicker(XComponentContext xContext) {
this.xContext = xContext;
}
/** Get a user selected path with a folder picker
*
* @return the path or null if the dialog is canceled
*/
public String getPath() {
// Create FolderPicker
Object folderPicker = null;
try {
folderPicker = xContext.getServiceManager().createInstanceWithContext("com.sun.star.ui.dialogs.FolderPicker", xContext);
}
catch (com.sun.star.uno.Exception e) {
return null;
}
// Display the FolderPicker
XFolderPicker xFolderPicker = (XFolderPicker) UnoRuntime.queryInterface(XFolderPicker.class, folderPicker);
XExecutableDialog xExecutable = (XExecutableDialog) UnoRuntime.queryInterface(XExecutableDialog.class, xFolderPicker);
// Get the path
String sPath = null;
if (xExecutable.execute() == ExecutableDialogResults.OK) {
sPath = xFolderPicker.getDirectory();
}
// Dispose the folder picker
XComponent xComponent = (XComponent) UnoRuntime.queryInterface(XComponent.class, folderPicker);
if (xComponent!=null) { // Seems not to be ??
xComponent.dispose();
}
return sPath;
}
}

View file

@ -0,0 +1,68 @@
/************************************************************************
*
* MacroExpander.java
*
* Copyright: 2002-2010 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.2 (2010-03-12)
*
*/
package org.openoffice.da.comp.w2lcommon.helper;
import com.sun.star.lang.IllegalArgumentException;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.util.XMacroExpander;
public class MacroExpander {
private XMacroExpander xExpander;
/** Convenience wrapper class for the UNO Macro Expander singleton
*
* @param xContext the UNO component context from which "theMacroExpander" can be created
*/
public MacroExpander(XComponentContext xContext) {
Object expander = xContext.getValueByName("/singletons/com.sun.star.util.theMacroExpander");
xExpander = (XMacroExpander) UnoRuntime.queryInterface (XMacroExpander.class, expander);
}
/** Expand macros in a string
*
* @param s the string
* @return the expanded string
*/
public String expandMacros(String s) {
if (xExpander!=null && s.startsWith("vnd.sun.star.expand:")) {
// The string contains a macro, usually as a result of using %origin% in the registry
s = s.substring(20);
try {
return xExpander.expandMacros(s);
}
catch (IllegalArgumentException e) {
// Unknown macro name found, proceed and hope for the best
return s;
}
}
else {
return s;
}
}
}

View file

@ -0,0 +1,104 @@
/************************************************************************
*
* MessageBox.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-02-16)
*
*/
package org.openoffice.da.comp.w2lcommon.helper;
import com.sun.star.awt.Rectangle;
import com.sun.star.awt.WindowAttribute;
import com.sun.star.awt.WindowClass;
import com.sun.star.awt.WindowDescriptor;
import com.sun.star.awt.XMessageBox;
import com.sun.star.awt.XToolkit;
import com.sun.star.awt.XWindowPeer;
import com.sun.star.frame.XDesktop;
import com.sun.star.frame.XFrame;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
/** This class provides simple access to a uno awt message box
*/
public class MessageBox {
private XFrame xFrame;
private XToolkit xToolkit;
/** Create a new MessageBox belonging to the current frame
*/
public MessageBox(XComponentContext xContext) {
this(xContext,null);
}
/** Create a new MessageBox belonging to a specific frame
*/
public MessageBox(XComponentContext xContext, XFrame xFrame) {
try {
Object toolkit = xContext.getServiceManager()
.createInstanceWithContext("com.sun.star.awt.Toolkit",xContext);
xToolkit = (XToolkit) UnoRuntime.queryInterface(XToolkit.class,toolkit);
if (xFrame==null) {
Object desktop = xContext.getServiceManager()
.createInstanceWithContext("com.sun.star.frame.Desktop",xContext);
XDesktop xDesktop = (XDesktop) UnoRuntime.queryInterface(XDesktop.class,desktop);
xFrame = xDesktop.getCurrentFrame();
}
this.xFrame = xFrame;
}
catch (Exception e) {
// Failed to get toolkit or frame
xToolkit = null;
xFrame = null;
}
}
public void showMessage(String sTitle, String sMessage) {
if (xToolkit==null || xFrame==null) { return; }
try {
WindowDescriptor descriptor = new WindowDescriptor();
descriptor.Type = WindowClass.MODALTOP;
descriptor.WindowServiceName = "infobox";
descriptor.ParentIndex = -1;
descriptor.Parent = (XWindowPeer) UnoRuntime.queryInterface(
XWindowPeer.class,xFrame.getContainerWindow());
descriptor.Bounds = new Rectangle(200,100,300,200);
descriptor.WindowAttributes = WindowAttribute.BORDER |
WindowAttribute.MOVEABLE | WindowAttribute.CLOSEABLE;
XWindowPeer xPeer = xToolkit.createWindow(descriptor);
if (xPeer!=null) {
XMessageBox xMessageBox = (XMessageBox)
UnoRuntime.queryInterface(XMessageBox.class,xPeer);
if (xMessageBox!=null) {
xMessageBox.setCaptionText(sTitle);
xMessageBox.setMessageText(sMessage);
xMessageBox.execute();
}
}
}
catch (Exception e) {
// ignore, give up...
}
}
}

View file

@ -0,0 +1,77 @@
/************************************************************************
*
* PropertyHelper.java
*
* Copyright: 2002-2008 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.0 (2008-07-21)
*
*/
package org.openoffice.da.comp.w2lcommon.helper;
import java.util.Enumeration;
import java.util.Hashtable;
import com.sun.star.beans.PropertyValue;
/** This class provides access by name to a <code>PropertyValue</code> array
*/
public class PropertyHelper {
private Hashtable<String, Object> data;
public PropertyHelper() {
data = new Hashtable<String, Object>();
}
public PropertyHelper(PropertyValue[] props) {
data = new Hashtable<String, Object>();
int nLen = props.length;
for (int i=0; i<nLen; i++) {
data.put(props[i].Name,props[i].Value);
}
}
public void put(String sName, Object value) {
data.put(sName,value);
}
public Object get(String sName) {
return data.get(sName);
}
public Enumeration<String> keys() {
return data.keys();
}
public PropertyValue[] toArray() {
int nSize = data.size();
PropertyValue[] props = new PropertyValue[nSize];
int i=0;
Enumeration<String> keys = keys();
while (keys.hasMoreElements()) {
String sKey = keys.nextElement();
props[i] = new PropertyValue();
props[i].Name = sKey;
props[i++].Value = get(sKey);
}
return props;
}
}

View file

@ -0,0 +1,85 @@
/**
* RegistryHelper.java
*
* Copyright: 2002-2009 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.2 (2009-05-01)
*
*
*/
package org.openoffice.da.comp.w2lcommon.helper;
import com.sun.star.beans.PropertyValue;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
/** This class defines convenience methods to access the OOo registry
* using a given base path
*/
public class RegistryHelper {
private XComponentContext xContext;
/** Construct a new RegistryHelper using a given component context
*
* @param xContext the context to use to create new services
*/
public RegistryHelper(XComponentContext xContext) {
this.xContext = xContext;
}
/** Get a registry view relative to the given path
*
* @param sPath the base path within the registry
* @param bUpdate true if we need update access
* @return the registry view
* @throws com.sun.star.uno.Exception
*/
public Object getRegistryView(String sPath, boolean bUpdate)
throws com.sun.star.uno.Exception {
//Object provider = xMSF.createInstance(
Object provider = xContext.getServiceManager().createInstanceWithContext(
"com.sun.star.configuration.ConfigurationProvider", xContext);
XMultiServiceFactory xProvider = (XMultiServiceFactory)
UnoRuntime.queryInterface(XMultiServiceFactory.class,provider);
PropertyValue[] args = new PropertyValue[1];
args[0] = new PropertyValue();
args[0].Name = "nodepath";
args[0].Value = sPath;
String sServiceName = bUpdate ?
"com.sun.star.configuration.ConfigurationUpdateAccess" :
"com.sun.star.configuration.ConfigurationAccess";
Object view = xProvider.createInstanceWithArguments(sServiceName,args);
return view;
}
/** Dispose a previously obtained registry view
*
* @param view the view to dispose
*/
public void disposeRegistryView(Object view) {
XComponent xComponent = (XComponent)
UnoRuntime.queryInterface(XComponent.class,view);
xComponent.dispose();
}
}

View file

@ -0,0 +1,78 @@
/************************************************************************
*
* SimpleDialog.java
*
* Copyright: 2002-2011 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.2 (2011-02-23)
*
*/
package org.openoffice.da.comp.w2lcommon.helper;
import com.sun.star.awt.XDialog;
import com.sun.star.awt.XDialogProvider2;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
/** This is a simple helper class to display and access a dialog based on an
* XML description (using the DialogProvider2 service).
* Unlike DialogBase, this class creates a dialog <em>without</em> event handlers.
*
* TODO: Use this class in ConfigurationDialogBase
*/
public class SimpleDialog {
private XDialog xDialog;
private DialogAccess dialogAccess;
/** Create a new dialog
*
* @param xContext the component context from which to get the service manager
* @param sDialogPath the path to the dialog
*/
public SimpleDialog(XComponentContext xContext, String sDialogPath) {
XMultiComponentFactory xMCF = xContext.getServiceManager();
try {
Object provider = xMCF.createInstanceWithContext("com.sun.star.awt.DialogProvider2", xContext);
XDialogProvider2 xDialogProvider = (XDialogProvider2) UnoRuntime.queryInterface(XDialogProvider2.class, provider);
String sDialogUrl = "vnd.sun.star.script:"+sDialogPath+"?location=application";
xDialog = xDialogProvider.createDialog(sDialogUrl);
dialogAccess = new DialogAccess(xDialog);
} catch (com.sun.star.uno.Exception e) {
xDialog = null;
dialogAccess = null;
}
}
/** Get the UNO dialog
*
* @return the dialog, or null if creation failed
*/
public XDialog getDialog() {
return xDialog;
}
/** Get access to the controls of the dialog
*
* @return the control access helper, or null if creation failed
*/
public DialogAccess getControls() {
return dialogAccess;
}
}

View file

@ -0,0 +1,54 @@
/************************************************************************
*
* StreamGobbler.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-04-05)
*
*/
package org.openoffice.da.comp.w2lcommon.helper;
import java.io.*;
public class StreamGobbler extends Thread {
InputStream is;
String type;
public StreamGobbler(InputStream is, String type) {
this.is = is;
this.type = type;
}
public void run() {
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
//String line=null;
//while ( (line = br.readLine()) != null) {
while ( br.readLine() != null) {
// Do nothing...
}
}
catch (IOException ioe) {
ioe.printStackTrace();
}
}
}

View file

@ -0,0 +1,142 @@
/************************************************************************
*
* StyleNameProvider.java
*
* Copyright: 2002-2009 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.2 (2009-11-08)
*
*/
package org.openoffice.da.comp.w2lcommon.helper;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import com.sun.star.beans.UnknownPropertyException;
import com.sun.star.beans.XPropertySet;
import com.sun.star.container.NoSuchElementException;
import com.sun.star.container.XNameAccess;
import com.sun.star.container.XNameContainer;
import com.sun.star.frame.XController;
import com.sun.star.frame.XDesktop;
import com.sun.star.frame.XModel;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.style.XStyleFamiliesSupplier;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
/** This class provides access to the style names and localized style names of the current document
*/
public class StyleNameProvider {
private Map<String,Map<String,String>> displayNameCollection;
private Map<String,Map<String,String>> internalNameCollection;
/** Construct a new <code>StyleNameProvider</code>
*
* @param xContext the componemt context to get the desktop from
*/
public StyleNameProvider(XComponentContext xContext) {
displayNameCollection = new HashMap<String,Map<String,String>>();
internalNameCollection = new HashMap<String,Map<String,String>>();
// Get the model for the current frame
XModel xModel = null;
try {
Object desktop = xContext.getServiceManager().createInstanceWithContext("com.sun.star.frame.Desktop", xContext);
XDesktop xDesktop = (XDesktop)UnoRuntime.queryInterface(XDesktop.class, desktop);
XController xController = xDesktop.getCurrentFrame().getController();
if (xController!=null) {
xModel = xController.getModel();
}
}
catch (Exception e) {
// do nothing
}
// Get the styles from the model
if (xModel!=null) {
XStyleFamiliesSupplier xSupplier = (XStyleFamiliesSupplier) UnoRuntime.queryInterface(
XStyleFamiliesSupplier.class, xModel);
if (xSupplier!=null) {
XNameAccess xFamilies = xSupplier.getStyleFamilies();
String[] sFamilyNames = xFamilies.getElementNames();
for (String sFamilyName : sFamilyNames) {
Map<String,String> displayNames = new HashMap<String,String>();
displayNameCollection.put(sFamilyName, displayNames);
Map<String,String> internalNames = new HashMap<String,String>();
internalNameCollection.put(sFamilyName, internalNames);
try {
XNameContainer xFamily = (XNameContainer) UnoRuntime.queryInterface(
XNameContainer.class, xFamilies.getByName(sFamilyName));
if (xFamily!=null) {
String[] sStyleNames = xFamily.getElementNames();
for (String sStyleName : sStyleNames) {
XPropertySet xProps = (XPropertySet) UnoRuntime.queryInterface(
XPropertySet.class, xFamily.getByName(sStyleName));
if (xProps!=null) {
String sDisplayName = (String) xProps.getPropertyValue("DisplayName");
displayNames.put(sStyleName, sDisplayName);
internalNames.put(sDisplayName, sStyleName);
}
}
}
}
catch (WrappedTargetException e) {
// ignore
}
catch (NoSuchElementException e) {
// will not happen
}
catch (UnknownPropertyException e) {
// will not happen
}
}
}
}
}
/** Get the mapping of internal names to display names for a style family
*
* @param sFamily the style family (for text documents this should be CharacterStyles, ParagraphStyles, FrameStyles, PageStyles or NumberingStyles)
* @return a read only map from internal names to display names, or null if the family is not known to the provider
*/
public Map<String,String> getDisplayNames(String sFamily) {
if (displayNameCollection.containsKey(sFamily)) {
return Collections.unmodifiableMap(displayNameCollection.get(sFamily));
}
return null;
}
/** Get the mapping of display names to internal names for a style family
*
* @param sFamily the style family (for text documents this should be CharacterStyles, ParagraphStyles, FrameStyles, PageStyles or NumberingStyles)
* @return a read only map from display names to internal names, or null if the family is not known to the provider
*/
public Map<String,String> getInternalNames(String sFamily) {
if (internalNameCollection.containsKey(sFamily)) {
return Collections.unmodifiableMap(internalNameCollection.get(sFamily));
}
return null;
}
}

View file

@ -0,0 +1,99 @@
/************************************************************************
*
* XPropertySetHelper.java
*
* Copyright: 2002-2008 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.0 (2008-07-21)
*
*/
package org.openoffice.da.comp.w2lcommon.helper;
import com.sun.star.beans.PropertyVetoException;
import com.sun.star.beans.UnknownPropertyException;
import com.sun.star.beans.XPropertySet;
import com.sun.star.lang.IllegalArgumentException;
import com.sun.star.lang.WrappedTargetException;
/** Helper class providing staic convenience methods for accesing an XPropertySet
* The helpers will fail silently if names or data is provided, but the user is expected to
* apply them with correct data only...
*/
public class XPropertySetHelper {
public static Object getPropertyValue(XPropertySet xProps, String sName) {
try {
return xProps.getPropertyValue(sName);
}
catch (UnknownPropertyException e) {
return null;
}
catch (WrappedTargetException e) {
return null;
}
}
public static void setPropertyValue(XPropertySet xProps, String sName, Object value) {
try {
xProps.setPropertyValue(sName,value);
}
catch (UnknownPropertyException e) {
}
catch (PropertyVetoException e) { // unacceptable value
}
catch (IllegalArgumentException e) {
}
catch (WrappedTargetException e) {
}
}
public static String getPropertyValueAsString(XPropertySet xProps, String sName) {
Object value = getPropertyValue(xProps,sName);
return value instanceof String ? (String) value : "";
}
public static int getPropertyValueAsInteger(XPropertySet xProps, String sName) {
Object value = getPropertyValue(xProps,sName);
return value instanceof Integer ? ((Integer) value).intValue() : 0;
}
public static void setPropertyValue(XPropertySet xProps, String sName, int nValue) {
setPropertyValue(xProps,sName,new Integer(nValue));
}
public static short getPropertyValueAsShort(XPropertySet xProps, String sName) {
Object value = getPropertyValue(xProps,sName);
return value instanceof Short ? ((Short) value).shortValue() : 0;
}
public static void setPropertyValue(XPropertySet xProps, String sName, short nValue) {
setPropertyValue(xProps,sName,new Short(nValue));
}
public static boolean getPropertyValueAsBoolean(XPropertySet xProps, String sName) {
Object value = getPropertyValue(xProps,sName);
return value instanceof Boolean ? ((Boolean) value).booleanValue() : false;
}
public static void setPropertyValue(XPropertySet xProps, String sName, boolean bValue) {
setPropertyValue(xProps,sName,new Boolean(bValue));
}
}

View file

@ -0,0 +1,48 @@
/************************************************************************
*
* Catcode.java
*
* Copyright: 2002-2009 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.2 (2009-06-11)
*
*/
package org.openoffice.da.comp.w2lcommon.tex.tokenizer;
/** This enumerates TeX category codes (catcodes) for characters as defined in
* chapter 7 of "The TeXbook"
*/
public enum Catcode {
ESCAPE,
BEGIN_GROUP,
END_GROUP,
MATH_SHIFT,
ALIGNMENT_TAB,
END_OF_LINE,
PARAMETER,
SUPERSCRIPT,
SUBSCRIPT,
IGNORED,
SPACE,
LETTER,
OTHER,
ACTIVE,
COMMENT,
INVALID;
}

View file

@ -0,0 +1,94 @@
/************************************************************************
*
* CatcodeTable.java
*
* Copyright: 2002-2009 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.2 (2009-06-11)
*
*/
package org.openoffice.da.comp.w2lcommon.tex.tokenizer;
/** This class maintains a mapping from characters to catcodes.
* In this implementation, non-ascii characters always has the
* category Catcode.OTHER.
*/
public class CatcodeTable {
private Catcode[] catcodes;
/** Construct a new <code>CatcodeTable</code>, defining catcodes
* as by INITeX plus the additional catcodes defined by plain TeX
*/
public CatcodeTable() {
catcodes = new Catcode[128];
// First define all the catcodes from INITeX (Chapter 7 in "The TeXbook")
for (int i=0; i<128; i++) {
catcodes[i] = Catcode.OTHER;
}
for (char c='A'; c<='Z'; c++) {
catcodes[c] = Catcode.LETTER;
}
for (char c='a'; c<='z'; c++) {
catcodes[c] = Catcode.LETTER;
}
catcodes['\r']=Catcode.END_OF_LINE;
catcodes[' ']=Catcode.SPACE;
catcodes['\u0000']=Catcode.IGNORED; // ASCII NUL
catcodes['\u007F']=Catcode.INVALID; // ASCII DEL
catcodes['%']=Catcode.COMMENT;
catcodes['\\']=Catcode.ESCAPE;
// Then define all the catcodes from plain TeX (Appendix B in "The TeXbook")
catcodes['{']=Catcode.BEGIN_GROUP;
catcodes['}']=Catcode.END_GROUP;
catcodes['$']=Catcode.MATH_SHIFT;
catcodes['&']=Catcode.ALIGNMENT_TAB;
catcodes['#']=Catcode.PARAMETER;
catcodes['^']=Catcode.SUPERSCRIPT;
catcodes['\u000B']=Catcode.SUPERSCRIPT; // ASCII VT ("uparrow")
catcodes['_']=Catcode.SUBSCRIPT;
catcodes['\u0001']=Catcode.SUBSCRIPT; // ASCII SOH ("downarrow")
catcodes['\t']=Catcode.SPACE;
catcodes['~']=Catcode.ACTIVE;
catcodes['\u000C']=Catcode.ACTIVE; // ASCII FF
}
/** Set the catcode of a character. The request is silently ignored
* for all characters outside the ASCII character set
*
* @param c the character
* @param cc the desired catcode
*/
public void set(char c, Catcode cc) {
if (c<128) { catcodes[c]=cc; }
}
/** Get the catcode of a character. Characters outside the ASCII character
* set always have the catcode Catcode.OTHER
*
* @param c the character
* @return the current catcode
*/
public Catcode get(char c) {
if (c<128) { return catcodes[c]; }
else { return Catcode.OTHER; }
}
}

View file

@ -0,0 +1,342 @@
/************************************************************************
*
* Mouth.java
*
* Copyright: 2002-2010 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.2 (2010-10-25)
*
*/
package org.openoffice.da.comp.w2lcommon.tex.tokenizer;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
enum State {
N, // new line
M, // middle of line
S; // ignoring spaces
}
/** <p>The Mouth is the main class of this package. It is a tokenizer to TeX files: According to "The TeXBook", the
* "eyes" and "mouth" of TeX are responsible for turning the input to TeX into a sequence of tokens.
* We are not going to reimplement TeX, but rather providing a service for parsing high-level languages based on
* TeX (eg. LaTeX, ConTeXt). For this reason the tokenizer deviates slightly from TeX: We're not reading a stream
* of bytes but rather a stream of characters (which makes no difference for ASCII files).</p>
*
* <p>In tribute to Donald E. Knuths digestive metaphors, we divide the process in four levels</p>
* <ul>
* <li>The parser should provide a <em>pair of glasses</em> to translate the stream of bytes into a stream of characters</li>
* <li>The <em>eyes</em> sees the stream of characters as a sequence of lines</li>
* <li>The <em>mouth</em> chews a bit on the characters to turn them into tokens</li>
* <li>The <em>tongue</em> reports the "taste" of the token to the parser</li>
* </ul>
*/
public class Mouth {
private Reader reader; // The input
private CatcodeTable catcodes; // The current catcode table
private char cEndlinechar; // The current value of \endlinechar
private Token token; // The token object
private State state; // The current state of the tokenizer
private Eyes eyes; // sic!
/** Construct a new <code>Mouth</code> based on a character stream
*
* @param reader the character stream to tokenize
* @throws IOException if we fail to read the character stream
*/
public Mouth(Reader reader) throws IOException {
this.reader = reader;
catcodes = new CatcodeTable();
cEndlinechar = '\r';
token = new Token();
state = State.N;
eyes = new Eyes();
}
private class Eyes {
private BufferedReader br; // The input
private String sLine; // The current line
private int nLen; // The length of the current line
private int nIndex; // The current index in the current line
Eyes() throws IOException {
br = new BufferedReader(reader);
nextLine();
}
/** Start looking at the next line of input
*
* @throws IOException if we fail to read the underlying stream
*/
void nextLine() throws IOException {
sLine = br.readLine();
if (sLine!=null) {
nLen = sLine.length();
nIndex = 0;
// Delete trailing spaces
while (nLen>0 && sLine.charAt(nLen-1)==' ') { nLen--; }
}
else { // end of stream
nLen = 0;
nIndex = 1;
}
}
/** Test whether the eyes are looking at a character
*
* @return true if the current line still has characters to look at
*/
boolean lookingAtChar() {
return nIndex<=nLen;
}
/** Test whether the eyes a looking at a line
*
* @return true if a current line is available
*/
boolean lookingAtLine() {
return sLine!=null;
}
/** Get the character that the eyes currently sees
*
* @return the character or U+FFFF if the eyes are not looking at a character
*/
char peekChar() {
return getChar(false);
}
/** Get the character that the eyes currently sees and start looking at the next character
*
* @return the character or U+FFFF if the eyes are not looking at a character
*/
char getChar() {
return getChar(true);
}
private char getChar(boolean bMove) {
if (nIndex<nLen) {
char c = sLine.charAt(nIndex);
if (catcodes.get(c)==Catcode.SUPERSCRIPT && nIndex+2<nLen && catcodes.get(sLine.charAt(nIndex+1))==Catcode.SUPERSCRIPT) {
// Found ^^ and at least one more character
char c1 = sLine.charAt(nIndex+2);
if (nIndex+3<nLen && isHex(c1)) {
char c2 = sLine.charAt(nIndex+3);
if (isHex(c2)) {
// Found ^^ and a lower case hexadecimal number
if (bMove) { nIndex+=4; }
char[] digits = {c1, c2};
return (char) Integer.parseInt(new String(digits), 16);
}
}
else if (c1<128) {
// Found ^^ and an ASCII character
if (bMove) { nIndex+=3; }
if (c1<64) { return (char)(c1+64); }
else { return (char)(c1-64); }
}
}
// Found an ordinary character!
if (bMove) { nIndex++; }
return c;
}
else if (nIndex==nLen) {
// Add \endlinechar at the end of the line
if (bMove) { nIndex++; }
return cEndlinechar;
}
else {
// No more characters on the current line
return '\uFFFF';
}
}
private boolean isHex(char c) {
return ('0'<=c && c<='9') || ('a'<=c && c<='z');
}
}
/** Get the currently used catcode table
*
* @return the table
*/
public CatcodeTable getCatcodes() {
return catcodes;
}
/** Set the catcode table. The catcode table can be changed at any time during tokenization.
*
* @param catcodes the table
*/
public void setCatcodes(CatcodeTable catcodes) {
this.catcodes = catcodes;
}
/** Return the current value of the \endlinechar (the character added to the end of each input line)
*
* @return the character
*/
public char getEndlinechar() {
return cEndlinechar;
}
/** Set a new \endlinechar (the character added to the end of each input line). The character can be changed at
* any time during tokenization.
*
* @param c the character
*/
public void setEndlinechar(char c) {
cEndlinechar = c;
}
/** Return the object used to store the current token (the "tongue" of TeX).
* The same object is reused for all tokens, so for convenience the parser can keep a reference to the object.
* If on the other hand the parser needs to store a token list, it must explicitly clone all tokens.
*
* @return the token
*/
public Token getTokenObject() {
return token;
}
/** Get the next token
*
* @return the token (for convenience; the same object is returned by {@link Mouth#getTokenObject}).
* @throws IOException if we fail to read the underlying stream
*/
public Token getToken() throws IOException {
while (eyes.lookingAtLine()) {
while (eyes.lookingAtChar()) {
char c = eyes.getChar();
switch (catcodes.get(c)) {
case ESCAPE:
token.setType(TokenType.COMMAND_SEQUENCE);
token.clearChars();
// TODO: The description in the TeXBook is not completely clear (to me anyway),
// (as long as \r and no other character has catcode END_OF_LINE this should be correct)
if (catcodes.get(eyes.peekChar())==Catcode.LETTER) {
state = State.S;
while (eyes.lookingAtChar() && catcodes.get(eyes.peekChar())==Catcode.LETTER) {
token.addChar(eyes.getChar());
}
}
else if (catcodes.get(eyes.peekChar())==Catcode.SPACE) {
state = State.S;
token.setChar(eyes.getChar());
}
else if (catcodes.get(eyes.peekChar())!=Catcode.END_OF_LINE) {
state = State.M;
token.setChar(eyes.getChar());
}
else {
// Empty control sequence
state = State.M;
}
return token;
case BEGIN_GROUP:
state = State.M;
token.set(c, TokenType.BEGIN_GROUP);
return token;
case END_GROUP:
state = State.M;
token.set(c, TokenType.END_GROUP);
return token;
case MATH_SHIFT:
state = State.M;
token.set(c, TokenType.MATH_SHIFT);
return token;
case ALIGNMENT_TAB:
state = State.M;
token.set(c, TokenType.ALIGNMENT_TAB);
return token;
case END_OF_LINE:
// Skip rest of line
while (eyes.lookingAtChar()) { eyes.getChar(); }
switch (state) {
case N:
// This terminates an empty line -> insert a \par
token.setType(TokenType.COMMAND_SEQUENCE);
token.clearChars();
token.addChar('p');
token.addChar('a');
token.addChar('r');
return token;
case M:
// Replace with a space token
token.set(' ', TokenType.SPACE);
return token;
case S:
// ignore the character
}
break;
case PARAMETER:
state = State.M;
token.set(c, TokenType.PARAMETER);
return token;
case SUPERSCRIPT:
state = State.M;
token.set(c, TokenType.SUPERSCRIPT);
return token;
case SUBSCRIPT:
state = State.M;
token.set(c, TokenType.SUBSCRIPT);
return token;
case IGNORED:
// ignore this character
break;
case SPACE:
if (state==State.M) {
state=State.S;
token.set(' ', TokenType.SPACE);
return token;
}
// In state N and S the space character is ignored
break;
case LETTER:
state = State.M;
token.set(c, TokenType.LETTER);
return token;
case OTHER:
state = State.M;
token.set(c, TokenType.OTHER);
return token;
case ACTIVE:
state = State.M;
token.set(c, TokenType.ACTIVE);
return token;
case COMMENT:
// Skip rest of line
while (eyes.lookingAtChar()) { eyes.getChar(); }
break;
case INVALID:
// ignore this character (should issue an error message, but we ignore that)
}
}
eyes.nextLine();
state = State.N;
}
// Nothing more to read
token.setType(TokenType.ENDINPUT);
token.clearChars();
return token;
}
}

View file

@ -0,0 +1,166 @@
/************************************************************************
*
* Token.java
*
* Copyright: 2002-2010 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.2 (2010-10-25)
*
*/
package org.openoffice.da.comp.w2lcommon.tex.tokenizer;
/** This class represent a token in TeX
*/
public class Token implements Cloneable {
private TokenType type;
private char[] tokenChars;
private int nTokenLen;
private int nCapacity;
/** Construct a new <code>Token</code>, initialized as a <code>TokenTYPE.ENDINPUT</code>-token
*/
public Token() {
type = TokenType.ENDINPUT;
tokenChars = new char[25];
nCapacity = 25;
nTokenLen = 0;
}
/** Set the type of this token to a specific <code>TokenType</code>
* (the character content is not changed)
*
* @param type the new <code>TokenType</code>
*/
protected void setType(TokenType type) {
this.type = type;
}
/** Set the character content of this token to a single character
* (the type of the token is not changed)
*
* @param c the character
*/
protected void setChar(char c) {
tokenChars[0] = c;
nTokenLen = 1;
}
/** Set this token as a character token with a specific <code>TokenType</code>
*
* @param c the character
* @param type the <code>TokenType</code> to use
*/
protected void set(char c, TokenType type) {
setType(type);
setChar(c);
}
/** Delete the character content of this token
*/
protected void clearChars() {
nTokenLen = 0;
}
/** Append a character to the character content of this token
*
* @param c the character to be appended
*/
protected void addChar(char c) {
if (nTokenLen == nCapacity) {
char[] temp = tokenChars;
nCapacity+=25;
tokenChars = new char[nCapacity];
System.arraycopy(temp, 0, tokenChars, 0, temp.length);
}
tokenChars[nTokenLen++] = c;
}
/** Test wether this token is a character token of the given type (that is, a single character
* with a token type that is neither <code>COMMAND_SEQUENCE</code> nor <code>ENDINPUT</code>)
*
* @param c the character to test
* @param type the <code>TokenType</code> to test
* @return true if the test was successful
*/
public boolean is(char c, TokenType type) {
return this.type==type && type!=TokenType.COMMAND_SEQUENCE && type!=TokenType.ENDINPUT &&
nTokenLen==1 && tokenChars[0]==c;
}
/** Test wether this token is a <code>COMMAND_SEQUENCE</code> token with a given name
*
* @param sName the name of the command sequence
* @return true if the test was successful
*/
public boolean isCS(String sName) {
if (type==TokenType.COMMAND_SEQUENCE && sName.length()==nTokenLen) {
for (int i=0; i<nTokenLen; i++) {
if (sName.charAt(i)!=tokenChars[i]) { return false; }
}
return true;
}
return false;
}
/** Get the <code>TokenType</code> of this token
*
* @return the type
*/
public TokenType getType() {
return type;
}
/** Get the first character in this token
*
* @return the character or U+FFFF is no characters exist
*/
public char getChar() {
return nTokenLen>0 ? tokenChars[0] : '\uFFFF';
}
/** Get the character content of this token as a string
*
* @return the character content
*/
public String getString() {
return new String(tokenChars,0,nTokenLen);
}
@Override public String toString() {
switch (type) {
case COMMAND_SEQUENCE:
return "\\"+getString();
case ENDINPUT:
return "<EOF>";
default:
return Character.toString(getChar());
}
}
@Override public Object clone() {
Token newToken = new Token();
newToken.type = this.type;
newToken.nTokenLen = this.nTokenLen;
newToken.nCapacity = this.nCapacity;
newToken.tokenChars = new char[newToken.nCapacity];
System.arraycopy(this.tokenChars, 0, newToken.tokenChars, 0, newToken.nCapacity);
return newToken;
}
}

View file

@ -0,0 +1,49 @@
/************************************************************************
*
* TokenType.java
*
* Copyright: 2002-2009 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.2 (2009-06-11)
*
*/
package org.openoffice.da.comp.w2lcommon.tex.tokenizer;
/** This enumerates possible TeX tokens. According to chapter 7 in
* "The TeX book", a token is either a character with an associated
* catcode or a control sequence. We add "end of input" token as
* a convenience. Not all catcodes can actually end up in a token,
* so we only include the relevant ones.
*/
public enum TokenType {
ESCAPE,
BEGIN_GROUP,
END_GROUP,
MATH_SHIFT,
ALIGNMENT_TAB,
PARAMETER,
SUPERSCRIPT,
SUBSCRIPT,
SPACE,
LETTER,
OTHER,
ACTIVE,
COMMAND_SEQUENCE,
ENDINPUT;
}

View file

@ -0,0 +1,480 @@
/************************************************************************
*
* ApplicationsDialog.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-05-29)
*
*/
package org.openoffice.da.comp.writer2latex;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Vector;
import com.sun.star.awt.XContainerWindowEventHandler;
import com.sun.star.awt.XDialog;
import com.sun.star.awt.XDialogProvider2;
import com.sun.star.awt.XWindow;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.uno.AnyConverter;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.lib.uno.helper.WeakBase;
import org.openoffice.da.comp.w2lcommon.helper.DialogAccess;
import org.openoffice.da.comp.w2lcommon.helper.FilePicker;
import org.openoffice.da.comp.w2lcommon.helper.StreamGobbler;
/** This class provides a UNO component which implements the configuration
* of applications for the Writer2LaTeX toolbar
*/
public final class ApplicationsDialog
extends WeakBase
implements XServiceInfo, XContainerWindowEventHandler {
private XComponentContext xContext;
private FilePicker filePicker;
private ExternalApps externalApps;
/** The component will be registered under this name.
*/
public static String __serviceName = "org.openoffice.da.writer2latex.ApplicationsDialog"; //$NON-NLS-1$
/** The component should also have an implementation name.
*/
public static String __implementationName = "org.openoffice.da.comp.writer2latex.ApplicationsDialog"; //$NON-NLS-1$
/** Create a new ApplicationsDialog */
public ApplicationsDialog(XComponentContext xContext) {
this.xContext = xContext;
externalApps = new ExternalApps(xContext);
filePicker = new FilePicker(xContext);
}
// **** Implement XContainerWindowEventHandler
public boolean callHandlerMethod(XWindow xWindow, Object event, String sMethod)
throws com.sun.star.lang.WrappedTargetException {
XDialog xDialog = (XDialog)UnoRuntime.queryInterface(XDialog.class, xWindow);
DialogAccess dlg = new DialogAccess(xDialog);
try {
if (sMethod.equals("external_event") ){ //$NON-NLS-1$
return handleExternalEvent(dlg, event);
}
else if (sMethod.equals("AfterExportChange")) { //$NON-NLS-1$
return changeProcessingLevel(dlg);
}
else if (sMethod.equals("ApplicationChange")) { //$NON-NLS-1$
return changeApplication(dlg);
}
else if (sMethod.equals("UseDefaultChange")) { //$NON-NLS-1$
return useDefaultChange(dlg) && updateApplication(dlg);
}
else if (sMethod.equals("BrowseClick")) { //$NON-NLS-1$
return browseForExecutable(dlg);
}
else if (sMethod.equals("ExecutableUnfocus")) { //$NON-NLS-1$
return updateApplication(dlg);
}
else if (sMethod.equals("OptionsUnfocus")) { //$NON-NLS-1$
return updateApplication(dlg);
}
else if (sMethod.equals("AutomaticClick")) { //$NON-NLS-1$
return autoConfigure(dlg);
}
}
catch (com.sun.star.uno.RuntimeException e) {
throw e;
}
catch (com.sun.star.uno.Exception e) {
throw new com.sun.star.lang.WrappedTargetException(sMethod, this, e);
}
return false;
}
public String[] getSupportedMethodNames() {
String[] sNames = { "external_event", "AfterExportChange", "ApplicationChange", "BrowseClick", "ExecutableUnfocus", "OptionsUnfocus", "AutomaticClick" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
return sNames;
}
// **** Implement the interface XServiceInfo
public boolean supportsService(String sServiceName) {
return sServiceName.equals(__serviceName);
}
public String getImplementationName() {
return __implementationName;
}
public String[] getSupportedServiceNames() {
String[] sSupportedServiceNames = { __serviceName };
return sSupportedServiceNames;
}
// **** Event handlers
private boolean handleExternalEvent(DialogAccess dlg, Object aEventObject)
throws com.sun.star.uno.Exception {
try {
String sMethod = AnyConverter.toString(aEventObject);
if (sMethod.equals("ok")) { //$NON-NLS-1$
externalApps.save();
return true;
} else if (sMethod.equals("back") || sMethod.equals("initialize")) { //$NON-NLS-1$ //$NON-NLS-2$
externalApps.load();
updateProcessingLevel(dlg);
return changeApplication(dlg);
}
}
catch (com.sun.star.lang.IllegalArgumentException e) {
throw new com.sun.star.lang.IllegalArgumentException(
"Method external_event requires a string in the event object argument.", this,(short) -1); //$NON-NLS-1$
}
return false;
}
private boolean changeProcessingLevel(DialogAccess dlg) {
externalApps.setProcessingLevel(dlg.getListBoxSelectedItem("AfterExport")); //$NON-NLS-1$
return true;
}
private boolean updateProcessingLevel(DialogAccess dlg) {
dlg.setListBoxSelectedItem("AfterExport", externalApps.getProcessingLevel()); //$NON-NLS-1$
return true;
}
private boolean changeApplication(DialogAccess dlg) {
String sAppName = getSelectedAppName(dlg);
if (sAppName!=null) {
String[] s = externalApps.getApplication(sAppName);
dlg.setComboBoxText("Executable", s[0]); //$NON-NLS-1$
dlg.setComboBoxText("Options", s[1]); //$NON-NLS-1$
dlg.setCheckBoxStateAsBoolean("UseDefault", externalApps.getUseDefaultApplication(sAppName)); //$NON-NLS-1$
dlg.setControlEnabled("UseDefault", externalApps.isViewer(sAppName)); //$NON-NLS-1$
useDefaultChange(dlg);
}
return true;
}
private boolean useDefaultChange(DialogAccess dlg) {
boolean bCustomApp = !dlg.getCheckBoxStateAsBoolean("UseDefault"); //$NON-NLS-1$
dlg.setControlEnabled("ExecutableLabel", bCustomApp); //$NON-NLS-1$
dlg.setControlEnabled("Executable", bCustomApp); //$NON-NLS-1$
dlg.setControlEnabled("OptionsLabel", bCustomApp); //$NON-NLS-1$
dlg.setControlEnabled("Options", bCustomApp); //$NON-NLS-1$
dlg.setControlEnabled("BrowseButton", bCustomApp); //$NON-NLS-1$
return true;
}
private boolean browseForExecutable(DialogAccess dlg) {
String sPath = filePicker.getPath();
if (sPath!=null) {
try {
dlg.setComboBoxText("Executable", new File(new URI(sPath)).getCanonicalPath()); //$NON-NLS-1$
}
catch (IOException e) {
}
catch (URISyntaxException e) {
}
updateApplication(dlg);
}
return true;
}
private boolean updateApplication(DialogAccess dlg) {
String sAppName = getSelectedAppName(dlg);
if (sAppName!=null) {
externalApps.setApplication(sAppName, dlg.getComboBoxText("Executable"), dlg.getComboBoxText("Options")); //$NON-NLS-1$ //$NON-NLS-2$
externalApps.setUseDefaultApplication(sAppName, dlg.getCheckBoxStateAsBoolean("UseDefault")); //$NON-NLS-1$
}
return true;
}
private boolean autoConfigure(DialogAccess dlg) {
String sOsName = System.getProperty("os.name"); //$NON-NLS-1$
String sOsVersion = System.getProperty("os.version"); //$NON-NLS-1$
String sOsArch = System.getProperty("os.arch"); //$NON-NLS-1$
StringBuilder info = new StringBuilder();
info.append(Messages.getString("ApplicationsDialog.configresults")+":\n\n"); //$NON-NLS-1$ //$NON-NLS-2$
info.append(Messages.getString("ApplicationsDialog.systemident")+" "+sOsName+" "+Messages.getString("ApplicationsDialog.version")+" "+sOsVersion+ " (" + sOsArch +")\n\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
if (sOsName.startsWith("Windows")) { //$NON-NLS-1$
autoConfigureWindows(dlg, info);
}
else {
autoConfigureUnix(dlg, info);
}
displayAutoConfigInfo(info.toString());
changeApplication(dlg);
return true;
}
private void displayAutoConfigInfo(String sText) {
XDialog xDialog = getDialog("W2LDialogs2.AutoConfigInfo"); //$NON-NLS-1$
if (xDialog!=null) {
DialogAccess info = new DialogAccess(xDialog);
info.setTextFieldText("Info", sText); //$NON-NLS-1$
xDialog.execute();
xDialog.endExecute();
}
}
private XDialog getDialog(String sDialogName) {
XMultiComponentFactory xMCF = xContext.getServiceManager();
try {
Object provider = xMCF.createInstanceWithContext(
"com.sun.star.awt.DialogProvider2", xContext); //$NON-NLS-1$
XDialogProvider2 xDialogProvider = (XDialogProvider2)
UnoRuntime.queryInterface(XDialogProvider2.class, provider);
String sDialogUrl = "vnd.sun.star.script:"+sDialogName+"?location=application"; //$NON-NLS-1$ //$NON-NLS-2$
return xDialogProvider.createDialogWithHandler(sDialogUrl, this);
}
catch (Exception e) {
return null;
}
}
private String getSelectedAppName(DialogAccess dlg) {
short nItem = dlg.getListBoxSelectedItem("Application"); //$NON-NLS-1$
//String sAppName = null;
switch (nItem) {
case 0: return ExternalApps.LATEX;
case 1: return ExternalApps.PDFLATEX;
case 2: return ExternalApps.XELATEX;
case 3: return ExternalApps.DVIPS;
case 4: return ExternalApps.BIBTEX;
case 5: return ExternalApps.MAKEINDEX;
//case 6: return ExternalApps.MK4HT;
case 6: return ExternalApps.DVIVIEWER;
case 7: return ExternalApps.PDFVIEWER;
case 8: return ExternalApps.POSTSCRIPTVIEWER;
}
return "???"; //$NON-NLS-1$
}
// **** Automatic configuration of applications for Windows systems (assuming MikTeX)
private void autoConfigureWindows(DialogAccess dlg, StringBuilder info) {
String sMikTeXPath = getMikTeXPath();
// Configure TeX and friends + yap (DVi viewer) + TeXworks (PDF viewer)
boolean bFoundTexworks = false;
if (sMikTeXPath!=null) {
info.append(Messages.getString("ApplicationsDialog.foundmiktex")+"\n"); //$NON-NLS-1$ //$NON-NLS-2$
configureMikTeX(sMikTeXPath, ExternalApps.LATEX, "latex", "--interaction=batchmode %s", info, true); //$NON-NLS-1$ //$NON-NLS-2$
configureMikTeX(sMikTeXPath, ExternalApps.PDFLATEX, "pdflatex", "--interaction=batchmode %s", info, true); //$NON-NLS-1$ //$NON-NLS-2$
configureMikTeX(sMikTeXPath, ExternalApps.XELATEX, "xelatex", "--interaction=batchmode %s", info, true); //$NON-NLS-1$ //$NON-NLS-2$
configureMikTeX(sMikTeXPath, ExternalApps.DVIPS, "dvips", "%s", info, true); //$NON-NLS-1$ //$NON-NLS-2$
configureMikTeX(sMikTeXPath, ExternalApps.BIBTEX, "bibtex", "%s", info, true); //$NON-NLS-1$ //$NON-NLS-2$
configureMikTeX(sMikTeXPath, ExternalApps.MAKEINDEX, "makeindex", "%s", info, true); //$NON-NLS-1$ //$NON-NLS-2$
//configureMikTeX(sMikTeXPath, ExternalApps.MK4HT, "mk4ht", "%c %s", info, true);
configureMikTeX(sMikTeXPath, ExternalApps.DVIVIEWER, "yap", "--single-instance %s", info, true); //$NON-NLS-1$ //$NON-NLS-2$
externalApps.setUseDefaultApplication(ExternalApps.DVIVIEWER, false);
// MikTeX 2.8 provides texworks for pdf viewing
bFoundTexworks = configureMikTeX(sMikTeXPath, ExternalApps.PDFVIEWER, "texworks", "%s", info, true); //$NON-NLS-1$ //$NON-NLS-2$
}
else {
info.append(Messages.getString("ApplicationsDialog.failedtofindmiktex")+"\n"); //$NON-NLS-1$ //$NON-NLS-2$
info.append(Messages.getString("ApplicationsDialog.miktexdefaultconfig")+"\n"); //$NON-NLS-1$ //$NON-NLS-2$
externalApps.setApplication(ExternalApps.LATEX, "latex", "--interaction=batchmode %s"); //$NON-NLS-1$ //$NON-NLS-2$
externalApps.setApplication(ExternalApps.PDFLATEX, "pdflatex", "--interaction=batchmode %s"); //$NON-NLS-1$ //$NON-NLS-2$
externalApps.setApplication(ExternalApps.XELATEX, "xelatex", "--interaction=batchmode %s"); //$NON-NLS-1$ //$NON-NLS-2$
externalApps.setApplication(ExternalApps.DVIPS, "dvips", "%s"); //$NON-NLS-1$ //$NON-NLS-2$
externalApps.setApplication(ExternalApps.BIBTEX, "bibtex", "%s"); //$NON-NLS-1$ //$NON-NLS-2$
externalApps.setApplication(ExternalApps.MAKEINDEX, "makeindex", "%s"); //$NON-NLS-1$ //$NON-NLS-2$
//externalApps.setApplication(ExternalApps.MK4HT, "mk4ht", "%c %s");
externalApps.setUseDefaultApplication(ExternalApps.DVIVIEWER, true);
}
externalApps.setUseDefaultApplication(ExternalApps.PDFVIEWER, !bFoundTexworks);
info.append("\n"); //$NON-NLS-1$
// Configure gsview (PostScript viewer and fall back viewer for PDF)
String sGsview = getGsviewPath();
if (sGsview!=null) {
info.append(Messages.getString("ApplicationsDialog.foundgsview")+" - "+Messages.getString("ApplicationsDialog.ok")+"\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
externalApps.setApplication(ExternalApps.POSTSCRIPTVIEWER, sGsview, "-e \"%s\""); //$NON-NLS-1$
if (!bFoundTexworks) {
externalApps.setApplication(ExternalApps.PDFVIEWER, sGsview, "-e \"%s\""); //$NON-NLS-1$
externalApps.setUseDefaultApplication(ExternalApps.PDFVIEWER, false);
}
}
else {
if (!bFoundTexworks) {
info.append(Messages.getString("ApplicationsDialog.pdfdefaultviewer")+"\n"); //$NON-NLS-1$ //$NON-NLS-2$
}
info.append(Messages.getString("ApplicationsDialog.psdefaultviewer")+"\n"); //$NON-NLS-1$ //$NON-NLS-2$
}
externalApps.setUseDefaultApplication(ExternalApps.POSTSCRIPTVIEWER, sGsview!=null);
}
// Windows: Get the path to the MikTeX bin directory
private String getMikTeXPath() {
String[] sPaths = System.getenv("PATH").split(";"); //$NON-NLS-1$ //$NON-NLS-2$
for (String s : sPaths) {
if (s.toLowerCase().indexOf("miktex")>-1 && containsExecutable(s,"latex.exe")) { //$NON-NLS-1$ //$NON-NLS-2$
return s;
}
}
for (String s : sPaths) {
if (containsExecutable(s,"latex.exe")) { //$NON-NLS-1$
return s;
}
}
return null;
}
// Windows: Get the path to the gsview executable
private String getGsviewPath() {
String sProgramFiles = System.getenv("ProgramFiles"); //$NON-NLS-1$
if (sProgramFiles!=null) {
if (containsExecutable(sProgramFiles+"\\ghostgum\\gsview","gsview32.exe")) { //$NON-NLS-1$ //$NON-NLS-2$
return sProgramFiles+"\\ghostgum\\gsview\\gsview32.exe"; //$NON-NLS-1$
}
}
return null;
}
// Windows: Test that the given path contains a given executable
private boolean containsExecutable(String sPath,String sExecutable) {
File dir = new File(sPath);
if (dir.exists() && dir.canRead()) {
File exe = new File(dir,sExecutable);
return exe.exists();
}
return false;
}
// Windows: Configure a certain MikTeX application
private boolean configureMikTeX(String sPath, String sName, String sAppName, String sArguments, StringBuilder info, boolean bRequired) {
File app = new File(new File(sPath),sAppName+".exe"); //$NON-NLS-1$
if (app.exists()) {
externalApps.setApplication(sName, sAppName, sArguments);
info.append(" "+Messages.getString("ApplicationsDialog.found")+" "+sName+": "+sAppName+" - "+Messages.getString("ApplicationsDialog.ok")+"\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
return true;
}
else if (bRequired) {
externalApps.setApplication(sName, "???", "???"); //$NON-NLS-1$ //$NON-NLS-2$
info.append(" "+Messages.getString("ApplicationsDialog.failedtofind")+" "+sName+"\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
return false;
}
// **** Automatic configuration of applications for other systems (assuming unix-like systems)
private void autoConfigureUnix(DialogAccess dlg, StringBuilder info) {
// Assume that the "which" command is supported
configureApp(ExternalApps.LATEX, "latex", "--interaction=batchmode %s",info); //$NON-NLS-1$ //$NON-NLS-2$
configureApp(ExternalApps.PDFLATEX, "pdflatex", "--interaction=batchmode %s",info); //$NON-NLS-1$ //$NON-NLS-2$
configureApp(ExternalApps.XELATEX, "xelatex", "--interaction=batchmode %s",info); //$NON-NLS-1$ //$NON-NLS-2$
configureApp(ExternalApps.DVIPS, "dvips", "%s",info); //$NON-NLS-1$ //$NON-NLS-2$
configureApp(ExternalApps.BIBTEX, "bibtex", "%s",info); //$NON-NLS-1$ //$NON-NLS-2$
configureApp(ExternalApps.MAKEINDEX, "makeindex", "%s",info); //$NON-NLS-1$ //$NON-NLS-2$
//configureApp(ExternalApps.MK4HT, "mk4ht", "%c %s",info);
// We have several possible viewers
String[] sDviViewers = {"evince", "okular", "xdvi"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
configureViewer(ExternalApps.DVIVIEWER, sDviViewers, "%s",info); //$NON-NLS-1$
String[] sPdfViewers = {"evince", "okular", "xpdf"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
configureViewer(ExternalApps.PDFVIEWER, sPdfViewers, "%s",info); //$NON-NLS-1$
String[] sPsViewers = {"evince", "okular", "ghostview"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
configureViewer(ExternalApps.POSTSCRIPTVIEWER, sPsViewers, "%s",info); //$NON-NLS-1$
// Maybe add some info for Debian/Ubuntu users, e.g.
// sudo apt-get install texlive
// sudo apt-get install texlive-xetex
// sudo apt-get install texlive-latex-extra
// sudo apt-get install tex4ht
}
// Unix: Test to determine whether a certain application is available in the OS
// Requires "which", hence Unix only
private boolean hasApp(String sAppName) {
try {
Vector<String> command = new Vector<String>();
command.add("which"); //$NON-NLS-1$
command.add(sAppName);
ProcessBuilder pb = new ProcessBuilder(command);
Process proc = pb.start();
// Gobble the error stream of the application
StreamGobbler errorGobbler = new
StreamGobbler(proc.getErrorStream(), "ERROR"); //$NON-NLS-1$
// Gobble the output stream of the application
StreamGobbler outputGobbler = new
StreamGobbler(proc.getInputStream(), "OUTPUT"); //$NON-NLS-1$
errorGobbler.start();
outputGobbler.start();
// The application exists if the process exits with 0
return proc.waitFor()==0;
}
catch (InterruptedException e) {
return false;
}
catch (IOException e) {
return false;
}
}
// Unix: Configure a certain application, testing and reporting the availability
private boolean configureApp(String sName, String sAppName, String sArguments, StringBuilder info) {
if (hasApp(sAppName)) {
externalApps.setApplication(sName, sAppName, sArguments);
externalApps.setUseDefaultApplication(sName, false);
if (info!=null) {
info.append(Messages.getString("ApplicationsDialog.found")+" "+sAppName+" - "+Messages.getString("ApplicationsDialog.ok")+"\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
}
return true;
}
else {
externalApps.setApplication(sName, "???", "???"); //$NON-NLS-1$ //$NON-NLS-2$
externalApps.setUseDefaultApplication(sName, false);
if (info!=null) {
info.append(Messages.getString("ApplicationsDialog.failedtofind")+" "+sAppName+"\n"); //$NON-NLS-1$ //$NON-NLS-2$
}
return false;
}
}
// Unix: Configure a certain application, testing and reporting the availability
// This variant uses an array of potential apps
private boolean configureViewer(String sName, String[] sAppNames, String sArguments, StringBuilder info) {
for (String sAppName : sAppNames) {
if (configureApp(sName, sAppName, sArguments, null)) {
info.append(Messages.getString("ApplicationsDialog.found")+" "+ExternalApps.getUIAppName(sName)+": "+sAppName+" - "+Messages.getString("ApplicationsDialog.ok")+"\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
return true;
}
}
externalApps.setUseDefaultApplication(sName, true);
info.append(Messages.getString("ApplicationsDialog.usingdefaultapp")+" "+ExternalApps.getUIAppName(sName)+"\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
return true;
}
}

View file

@ -0,0 +1,758 @@
/************************************************************************
*
* BibTeXDialog.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-07-28)
*
*/
package org.openoffice.da.comp.writer2latex;
import java.awt.Desktop;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import com.sun.star.awt.XDialog;
import com.sun.star.awt.XDialogProvider2;
import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.PropertyVetoException;
import com.sun.star.beans.UnknownPropertyException;
import com.sun.star.beans.XPropertySet;
import com.sun.star.container.NoSuchElementException;
import com.sun.star.container.XEnumeration;
import com.sun.star.container.XEnumerationAccess;
import com.sun.star.container.XIndexAccess;
import com.sun.star.frame.XFrame;
import com.sun.star.lang.IllegalArgumentException;
import com.sun.star.lang.IndexOutOfBoundsException;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.text.XDependentTextField;
import com.sun.star.text.XDocumentIndex;
import com.sun.star.text.XDocumentIndexesSupplier;
import com.sun.star.text.XText;
import com.sun.star.text.XTextDocument;
import com.sun.star.text.XTextField;
import com.sun.star.text.XTextFieldsSupplier;
import com.sun.star.text.XTextViewCursor;
import com.sun.star.text.XTextViewCursorSupplier;
import com.sun.star.ui.dialogs.ExecutableDialogResults;
import com.sun.star.uno.AnyConverter;
import com.sun.star.uno.Exception;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import org.jbibtex.ParseException;
import org.openoffice.da.comp.w2lcommon.helper.DialogAccess;
import org.openoffice.da.comp.w2lcommon.helper.DialogBase;
import org.openoffice.da.comp.w2lcommon.helper.MessageBox;
import org.openoffice.da.comp.w2lcommon.helper.RegistryHelper;
import org.openoffice.da.comp.w2lcommon.helper.XPropertySetHelper;
import writer2latex.latex.i18n.ClassicI18n;
import writer2latex.office.BibMark;
import writer2latex.office.BibMark.EntryType;
import writer2latex.util.Misc;
/** This class provides a UNO dialog to insert a BibTeX bibliographic reference
*/
public class BibTeXDialog extends DialogBase implements com.sun.star.lang.XInitialization {
// **** Data used for component registration
/** The component will be registered under this service name
*/
public static String __serviceName = "org.openoffice.da.writer2latex.BibTeXDialog"; //$NON-NLS-1$
/** The implementation name of the component
*/
public static String __implementationName = "org.openoffice.da.comp.writer2latex.BibTeXDialog"; //$NON-NLS-1$
// **** Member variables
// The current frame (passed at initialization)
XFrame xFrame = null;
// The BibTeX directory (passed at initialization)
File bibTeXDirectory = null;
// The encoding for BibTeX files (set in constructor from the registry)
String sBibTeXJavaEncoding = null;
// Cache of BibTeX files in the BibTeX directory
File[] files = null;
// Cache of the current BibTeX file
BibTeXReader currentFile = null;
// **** Implement com.sun.star.lang.XInitialization
// We expect to get the current frame and a comma separated list of BibTeX files to use
public void initialize( Object[] objects )
throws com.sun.star.uno.Exception {
for (Object object : objects) {
if (object instanceof XFrame) {
xFrame = UnoRuntime.queryInterface(XFrame.class, object);
}
if (object instanceof String) {
bibTeXDirectory = new File((String) object);
}
}
}
// **** Extend DialogBase
/** Create a new BibTeXDialog */
public BibTeXDialog(XComponentContext xContext) {
super(xContext);
sBibTeXJavaEncoding = getBibTeXJavaEncoding();
}
private String getBibTeXJavaEncoding() {
RegistryHelper registry = new RegistryHelper(xContext);
try {
Object view = registry.getRegistryView(BibliographyDialog.REGISTRY_PATH, false);
XPropertySet xProps = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class,view);
int nBibTeXEncoding = XPropertySetHelper.getPropertyValueAsShort(xProps, "BibTeXEncoding"); //$NON-NLS-1$
registry.disposeRegistryView(view);
return ClassicI18n.writeJavaEncoding(nBibTeXEncoding);
}
catch (Exception e) {
// Failed to get registry view
}
return null;
}
/** Return the name of the library containing the dialog
*/
@Override public String getDialogLibraryName() {
return "W2LDialogs2"; //$NON-NLS-1$
}
/** Return the name of the dialog within the library
*/
@Override public String getDialogName() {
return "BibTeXEntry"; //$NON-NLS-1$
}
@Override public void initialize() {
reload(null);
}
@Override public void endDialog() {
}
// **** Implement XDialogEventHandler
@Override public boolean callHandlerMethod(XDialog xDialog, Object event, String sMethod) {
clearUpdateLabel();
if (sMethod.equals("FileChange")) { //$NON-NLS-1$
// The user has selected another BibTeX file
fileChange();
}
else if (sMethod.equals("EntryChange")) { //$NON-NLS-1$
// The user has selected another BibTeX entry
entryChange();
}
else if (sMethod.equals("New")) { //$NON-NLS-1$
// Create a new BibTeX file
newFile();
}
else if (sMethod.equals("Edit")) { //$NON-NLS-1$
// Edit the current BibTeX file
edit();
}
else if (sMethod.equals("Reload")) { //$NON-NLS-1$
// Reload the BibTeX files in the dialog
reload(null);
}
else if (sMethod.equals("InsertReference")) { //$NON-NLS-1$
// Insert a reference to the current BibTeX entry
insertReference();
}
else if (sMethod.equals("Update")) { //$NON-NLS-1$
// Update all reference in the document
update();
}
return true;
}
@Override public String[] getSupportedMethodNames() {
String[] sNames = { "FileChange", "EntryChange", "New", "Edit", "Reload", "InsertReference", "Update" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
return sNames;
}
// **** Implement the UI functions
// Clear the contents of the update info label
private void clearUpdateLabel() {
setLabelText("UpdateLabel","");
}
// (Re)load the list of BibTeX files
private void reload(String sSelectedFileName) {
String sFile = null;
if (sSelectedFileName!=null) {
// Select a new file name
sFile = sSelectedFileName;
}
else {
// Remember the previous selection, if any
short nSelectedFile = getListBoxSelectedItem("File"); //$NON-NLS-1$
if (nSelectedFile>=0 && files[nSelectedFile]!=null) {
sFile = getListBoxStringItemList("File")[nSelectedFile]; //$NON-NLS-1$
}
}
if (bibTeXDirectory!=null && bibTeXDirectory.isDirectory()) {
// Populate the file list based on the BibTeX directory
files = bibTeXDirectory.listFiles(
new FilenameFilter() {
public boolean accept(File file, String sName) { return sName!=null && sName.endsWith(".bib"); } //$NON-NLS-1$
}
);
int nFileCount = files.length;
String[] sFileNames = new String[nFileCount];
// Select either the first or the previous item
short nFile = 0;
for (short i=0; i<nFileCount; i++) {
sFileNames[i] = files[i].getName();
if (sFileNames[i].equals(sFile)) { nFile = i; }
}
setListBoxStringItemList("File", sFileNames); //$NON-NLS-1$
setListBoxSelectedItem("File",(short)nFile); //$NON-NLS-1$
if (nFileCount>0) {
setControlEnabled("FileLabel",true); //$NON-NLS-1$
setControlEnabled("File",true); //$NON-NLS-1$
setControlEnabled("EntryLabel",true); //$NON-NLS-1$
setControlEnabled("Entry",true); //$NON-NLS-1$
setControlEnabled("Edit",true); //$NON-NLS-1$
setControlEnabled("Insert",true); //$NON-NLS-1$
setControlEnabled("Update",true); //$NON-NLS-1$
fileChange();
return;
}
}
// The directory did not contain any BibTeX files
setControlEnabled("FileLabel",false); //$NON-NLS-1$
setControlEnabled("File",false); //$NON-NLS-1$
setControlEnabled("EntryLabel",false); //$NON-NLS-1$
setControlEnabled("Entry",false); //$NON-NLS-1$
setControlEnabled("Edit",false); //$NON-NLS-1$
setControlEnabled("Insert",false); //$NON-NLS-1$
setControlEnabled("Update",false); //$NON-NLS-1$
setLabelText("EntryInformation",Messages.getString("BibTeXDialog.nobibtexfiles")); //$NON-NLS-1$ //$NON-NLS-2$
}
// Update the list of entries based on the current selection in the file list
private void fileChange() {
// Remember current entry selection, if any
String sEntry = null;
short nEntry = getListBoxSelectedItem("Entry"); //$NON-NLS-1$
if (nEntry>=0) {
sEntry = getListBoxStringItemList("Entry")[nEntry]; //$NON-NLS-1$
}
// Parse the selected file
int nFile = getListBoxSelectedItem("File"); //$NON-NLS-1$
if (nFile>=0) {
try {
currentFile = new BibTeXReader(files[nFile],sBibTeXJavaEncoding);
} catch (IOException e) {
System.err.println(e.getMessage());
currentFile = null;
} catch (ParseException e) {
System.err.println(e.getMessage());
currentFile = null;
}
if (currentFile!=null) {
// Populate the entry list with the keys from the current file, if any
String[] sCurrentKeys = currentFile.getEntries().keySet().toArray(new String[0]);
setListBoxStringItemList("Entry", sCurrentKeys); //$NON-NLS-1$
if (sCurrentKeys.length>0) {
// Select either the first or the previous entry
nEntry = 0;
if (sEntry!=null) {
int nEntryCount = sCurrentKeys.length;
for (short i=0; i<nEntryCount; i++) {
if (sEntry.equals(sCurrentKeys[i])) {
nEntry = i;
}
}
}
setListBoxSelectedItem("Entry",nEntry); //$NON-NLS-1$
setControlEnabled("EntryLabel",true); //$NON-NLS-1$
setControlEnabled("Entry",true); //$NON-NLS-1$
setControlEnabled("Insert",true); //$NON-NLS-1$
entryChange();
}
else { // No entries, disable controls
setControlEnabled("EntryLabel",false); //$NON-NLS-1$
setControlEnabled("Entry",false); //$NON-NLS-1$
setControlEnabled("Insert",false); //$NON-NLS-1$
setLabelText("EntryInformation",Messages.getString("BibTeXDialog.noentries")); //$NON-NLS-1$ //$NON-NLS-2$
}
setControlEnabled("Edit",true); //$NON-NLS-1$
}
else { // Failed to parse, disable controls
setListBoxStringItemList("Entry", new String[0]); //$NON-NLS-1$
setControlEnabled("EntryLabel",false); //$NON-NLS-1$
setControlEnabled("Entry",false); //$NON-NLS-1$
setControlEnabled("Edit",false); //$NON-NLS-1$
setControlEnabled("Insert",false); //$NON-NLS-1$
setLabelText("EntryInformation",Messages.getString("BibTeXDialog.errorreadingfile")); //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
// Update the entry information based on the current selection in the entry list
private void entryChange() {
BibMark bibMark = getCurrentEntry();
if (bibMark!=null) {
String sAuthor = bibMark.getField(EntryType.author);
if (sAuthor==null) { sAuthor = ""; } //$NON-NLS-1$
String sTitle = bibMark.getField(EntryType.title);
if (sTitle==null) { sTitle = ""; } //$NON-NLS-1$
String sPublisher = bibMark.getField(EntryType.publisher);
if (sPublisher==null) { sPublisher = ""; } //$NON-NLS-1$
String sYear = bibMark.getField(EntryType.year);
if (sYear==null) { sYear = ""; } //$NON-NLS-1$
setLabelText("EntryInformation", sAuthor+"\n"+sTitle+"\n"+sPublisher+"\n"+sYear); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
else {
setLabelText("EntryInformation", Messages.getString("BibTeXDialog.noinformation")); //$NON-NLS-1$ //$NON-NLS-2$
}
}
// Insert the currently selected entry as a reference in the text document
private void insertReference() {
insertReference(getCurrentEntry());
}
// Create a new BibTeX file
private void newFile() {
String sFileName = getFileName();
if (sFileName!=null) {
if (!sFileName.equals(".bib")) { //$NON-NLS-1$
File file = new File(bibTeXDirectory,sFileName);
try {
if (!file.createNewFile() && xFrame!=null) {
MessageBox msgBox = new MessageBox(xContext, xFrame);
msgBox.showMessage("Writer2LaTeX",Messages.getString("BibTeXDialog.thefile")+" "+sFileName+" "+Messages.getString("BibTeXDialog.alreadyexists")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
reload(sFileName);
} catch (IOException e) {
}
}
else if (xFrame!=null) {
MessageBox msgBox = new MessageBox(xContext, xFrame);
msgBox.showMessage("Writer2LaTeX",Messages.getString("BibTeXDialog.filenameempty")); //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
// Get a BibTeX file name from the user (possibly modified to a TeX friendly name)
private String getFileName() {
XDialog xDialog=getNewDialog();
if (xDialog!=null) {
DialogAccess ndlg = new DialogAccess(xDialog);
ndlg.setListBoxStringItemList("Name", new String[0]); //$NON-NLS-1$
String sResult = null;
if (xDialog.execute()==ExecutableDialogResults.OK) {
DialogAccess dlg = new DialogAccess(xDialog);
sResult = dlg.getTextFieldText("Name"); //$NON-NLS-1$
}
xDialog.endExecute();
if (sResult!=null && !sResult.toLowerCase().endsWith(".bib")) { //$NON-NLS-1$
sResult = sResult+".bib"; //$NON-NLS-1$
}
return Misc.makeTeXFriendly(sResult,"bibliography"); //$NON-NLS-1$
}
return null;
}
// Get the new dialog (reused from the configuration dialog)
protected XDialog getNewDialog() {
XMultiComponentFactory xMCF = xContext.getServiceManager();
try {
Object provider = xMCF.createInstanceWithContext("com.sun.star.awt.DialogProvider2", xContext); //$NON-NLS-1$
XDialogProvider2 xDialogProvider = (XDialogProvider2)
UnoRuntime.queryInterface(XDialogProvider2.class, provider);
String sDialogUrl = "vnd.sun.star.script:"+getDialogLibraryName()+".NewDialog?location=application"; //$NON-NLS-1$ //$NON-NLS-2$
return xDialogProvider.createDialog(sDialogUrl);
}
catch (Exception e) {
return null;
}
}
// Edit the currently selected BibTeX file, if any
private void edit() {
int nFile = getListBoxSelectedItem("File"); //$NON-NLS-1$
if (nFile>=0) {
if (files[nFile].exists()) {
edit(files[nFile]);
}
}
}
// Helper function: Get the currently selected entry, or null if none is selected
private BibMark getCurrentEntry() {
BibMark bibMark = null;
int nEntry = getListBoxSelectedItem("Entry"); //$NON-NLS-1$
if (nEntry>=0) {
String[] sCurrentKeys = getListBoxStringItemList("Entry"); //$NON-NLS-1$
String sKey = sCurrentKeys[nEntry];
bibMark = currentFile.getEntries().get(sKey);
}
return bibMark;
}
// **** Implement core functions
// Edit a BibTeX files using the systems default application, if any
private void edit(File file) {
if (Desktop.isDesktopSupported()) {
Desktop desktop = Desktop.getDesktop();
try {
desktop.open(file);
} catch (IOException e) {
if (xFrame!=null) {
MessageBox msgBox = new MessageBox(xContext, xFrame);
msgBox.showMessage("Writer2LaTeX",Messages.getString("BibTeXDialog.failedbibtexeditor")); //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
else if (xFrame!=null) {
MessageBox msgBox = new MessageBox(xContext, xFrame);
msgBox.showMessage("Writer2LaTeX",Messages.getString("BibTeXDialog.nobibtexeditor")); //$NON-NLS-1$ //$NON-NLS-2$
}
}
// Update all bibliographic fields in the document
private void update() {
if (xFrame!=null) {
BibTeXReader[] readers = parseAllBibTeXFiles();
// Collect identifiers of fields that were not updated (to inform the user)
Set<String> notUpdated = new HashSet<String>();
// Traverse all text fields and update all bibliography fields
XTextFieldsSupplier xSupplier = (XTextFieldsSupplier) UnoRuntime.queryInterface(
XTextFieldsSupplier.class, xFrame.getController().getModel());
XEnumerationAccess fields = xSupplier.getTextFields();
XEnumeration enumeration = fields.createEnumeration();
while (enumeration.hasMoreElements()) {
try {
Object elm = enumeration.nextElement();
if (AnyConverter.isObject(elm)) {
XTextField xTextField = (XTextField) AnyConverter.toObject(XTextField.class, elm);
if (xTextField!=null) {
XServiceInfo xInfo = UnoRuntime.queryInterface(XServiceInfo.class, xTextField);
if (xInfo.supportsService("com.sun.star.text.TextField.Bibliography")) { //$NON-NLS-1$
String sId = updateBibField(xTextField, readers);
if (sId!=null) {
notUpdated.add(sId);
}
}
}
}
} catch (NoSuchElementException e) {
} catch (WrappedTargetException e) {
}
}
// Traverse all indexes and update bibliographies
XDocumentIndexesSupplier xIndexSupplier = (XDocumentIndexesSupplier) UnoRuntime.queryInterface(
XDocumentIndexesSupplier.class, xFrame.getController().getModel());
XIndexAccess xIndexAccess = xIndexSupplier.getDocumentIndexes();
int nIndexCount = xIndexAccess.getCount();
for (int i=0; i<nIndexCount; i++) {
try {
Object indexElm = xIndexAccess.getByIndex(i);
if (AnyConverter.isObject(indexElm)) {
XDocumentIndex xDocumentIndex = (XDocumentIndex) AnyConverter.toObject(XDocumentIndex.class, indexElm);
if (xDocumentIndex!=null) {
if ("com.sun.star.text.Bibliography".equals(xDocumentIndex.getServiceName())) { //$NON-NLS-1$
xDocumentIndex.update();
}
}
}
} catch (IndexOutOfBoundsException e) {
} catch (WrappedTargetException e) {
}
}
// Inform the user about the result
//MessageBox msgBox = new MessageBox(xContext, xFrame);
if (notUpdated.isEmpty()) {
setLabelText("UpdateLabel",Messages.getString("BibTeXDialog.allbibfieldsupdated")); //$NON-NLS-1$ //$NON-NLS-2$
//msgBox.showMessage("Writer2LaTeX",Messages.getString("BibTeXDialog.allbibfieldsupdated")); //$NON-NLS-1$ //$NON-NLS-2$
}
else {
setLabelText("UpdateLabel",Messages.getString("BibTeXDialog.bibfieldsnotupdated")+":\n"+notUpdated.toString()); //$NON-NLS-1$ //$NON-NLS-2$
//msgBox.showMessage("Writer2LaTeX",Messages.getString("BibTeXDialog.bibfieldsnotupdated")+":\n"+notUpdated.toString()); //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
private BibTeXReader[] parseAllBibTeXFiles() {
int nFiles = files.length;
BibTeXReader[] readers = new BibTeXReader[nFiles];
for (int i=0; i<nFiles; i++) {
try {
readers[i] = new BibTeXReader(files[i],sBibTeXJavaEncoding);
} catch (IOException e) {
System.err.println(e.getMessage());
readers[i] = null;
} catch (ParseException e) {
System.err.println(e.getMessage());
readers[i] = null;
}
}
return readers;
}
// Update a bibliography field, returning the identifier on failure and null on success(!)
private String updateBibField(XTextField xTextField, BibTeXReader[] readers) {
XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xTextField);
if (xPropSet!=null) {
try {
Object fieldsObj = xPropSet.getPropertyValue("Fields");
if (fieldsObj!=null && fieldsObj instanceof PropertyValue[]) {
PropertyValue[] props = (PropertyValue[]) fieldsObj;
for (PropertyValue prop : props) {
if ("Identifier".equals(prop.Name)) {
if (prop.Value instanceof String) {
String sIdentifier = (String)prop.Value;
for (BibTeXReader reader : readers) {
if (reader.getEntries().keySet().contains(sIdentifier)) {
BibMark bibMark = reader.getEntries().get(sIdentifier);
try {
xPropSet.setPropertyValue("Fields", createBibliographyFields(bibMark));
return null;
} catch (IllegalArgumentException e) {
} catch (PropertyVetoException e) {
}
}
}
return sIdentifier;
}
}
}
}
} catch (UnknownPropertyException e) {
System.out.println(e.getMessage());
} catch (WrappedTargetException e) {
System.out.println(e.getMessage());
}
}
return null;
}
// Insert a bibliographic reference from a BibMark
private void insertReference(BibMark bibMark) {
if (xFrame!=null) {
try {
// To be able to manipulate the text we need to get the XText interface of the model
XTextDocument xTextDoc = UnoRuntime.queryInterface(
XTextDocument.class, xFrame.getController().getModel());
XText xText = xTextDoc.getText();
// To locate the current position, we need to get the XTextViewCursor from the controller
XTextViewCursorSupplier xViewCursorSupplier = UnoRuntime.queryInterface(
XTextViewCursorSupplier.class, xFrame.getController());
XTextViewCursor xViewCursor = xViewCursorSupplier.getViewCursor();
// To create a new bibliographic field, we need to get the document service factory
XMultiServiceFactory xDocFactory = UnoRuntime.queryInterface(
XMultiServiceFactory.class, xFrame.getController().getModel());
// Use the service factory to create a bibliography field
XDependentTextField xBibField = UnoRuntime.queryInterface (
XDependentTextField.class, xDocFactory.createInstance("com.sun.star.text.textfield.Bibliography"));
// Create a field master for the field
XPropertySet xMasterPropSet = UnoRuntime.queryInterface(
XPropertySet.class, xDocFactory.createInstance("com.sun.star.text.fieldmaster.Bibliography"));
// Populate the bibliography field
XPropertySet xPropSet = UnoRuntime.queryInterface(
XPropertySet.class, xBibField);
PropertyValue[] fields = createBibliographyFields(bibMark);
xPropSet.setPropertyValue("Fields", fields);
// Attach the field master to the bibliography field
xBibField.attachTextFieldMaster(xMasterPropSet);
// Finally, insert the field at the end of the cursor
xText.insertTextContent(xViewCursor.getEnd(), xBibField, false);
} catch (Exception e) {
}
}
}
// Create fields from a BibMark
private PropertyValue[] createBibliographyFields(BibMark bibMark) {
EntryType[] entryTypes = EntryType.values();
PropertyValue[] fields = new PropertyValue[entryTypes.length+2];
fields[0] = new PropertyValue();
fields[0].Name="Identifier";
fields[0].Value=bibMark.getIdentifier();
fields[1] = new PropertyValue();
fields[1].Name="BibiliographicType"; // sic! (API typo)
fields[1].Value=new Short(getBibliographicType(bibMark.getEntryType()));
int i=1;
for (EntryType entryType : entryTypes) {
fields[++i] = new PropertyValue();
fields[i].Name = getFieldName(entryType);
String sValue = bibMark.getField(entryType);
fields[i].Value = sValue!=null ? bibMark.getField(entryType) : "";
}
return fields;
}
// Translate entry type to field name
private String getFieldName(EntryType entryType) {
switch(entryType) {
case address: return "Address";
case annote: return "Annote";
case author: return "Author";
case booktitle: return "Booktitle";
case chapter : return "Chapter";
case edition: return "Edition";
case editor: return "Editor";
case howpublished: return "Howpublished";
case institution: return "Institution";
case journal: return "Journal";
case month: return "Month";
case note: return "Note";
case number: return "Number";
case organizations: return "Organizations";
case pages: return "Pages";
case publisher: return "Publisher";
case school: return "School";
case series: return "Series";
case title: return "Title";
case report_type: return "Report_Type";
case volume: return "Volume";
case year: return "Year";
case url: return "URL";
case custom1: return "Custom1";
case custom2: return "Custom2";
case custom3: return "Custom3";
case custom4: return "Custom4";
case custom5: return "Custom5";
case isbn: return "ISBN";
default: return null;
}
}
// Translate bibliographic type to internal code
private short getBibliographicType(String sBibType) {
String s = sBibType.toUpperCase();
if ("ARTICLE".equals(s)) {
return (short)0;
}
else if ("BOOK".equals(s)) {
return (short)1;
}
else if ("BOOKLET".equals(s)) {
return (short)2;
}
else if ("CONFERENCE".equals(s)) {
return (short)3;
}
else if ("INBOOK".equals(s)) {
return (short)4;
}
else if ("INCOLLECTION".equals(s)) {
return (short)5;
}
else if ("INPROCEEDINGS".equals(s)) {
return (short)6;
}
else if ("JOURNAL".equals(s)) {
return (short)7;
}
else if ("MANUAL".equals(s)) {
return (short)8;
}
else if ("MASTERSTHESIS".equals(s)) {
return (short)9;
}
else if ("MISC".equals(s)) {
return (short)10;
}
else if ("PHDTHESIS".equals(s)) {
return (short)11;
}
else if ("PROCEEDINGS".equals(s)) {
return (short)12;
}
else if ("TECHREPORT".equals(s)) {
return (short)13;
}
else if ("UNPUBLISHED".equals(s)) {
return (short)14;
}
else if ("EMAIL".equals(s)) {
return (short)15;
}
else if ("WWW".equals(s)) {
return (short)16;
}
else if ("CUSTOM1".equals(s)) {
return (short)17;
}
else if ("CUSTOM2".equals(s)) {
return (short)18;
}
else if ("CUSTOM3".equals(s)) {
return (short)19;
}
else if ("CUSTOM4".equals(s)) {
return (short)20;
}
else if ("CUSTOM5".equals(s)) {
return (short)21;
}
else {
return (short)10; // Use misc for unknown types
}
}
}

View file

@ -0,0 +1,169 @@
/************************************************************************
*
* BibTeXReader.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-07-24)
*
*/
package org.openoffice.da.comp.writer2latex;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.jbibtex.BibTeXDatabase;
import org.jbibtex.BibTeXEntry;
import org.jbibtex.BibTeXParser;
import org.jbibtex.BibTeXString;
import org.jbibtex.Key;
import org.jbibtex.LaTeXParser;
import org.jbibtex.LaTeXPrinter;
import org.jbibtex.ParseException;
import org.jbibtex.TokenMgrException;
import org.jbibtex.Value;
import writer2latex.bibtex.BibTeXEntryMap;
import writer2latex.office.BibMark;
import writer2latex.office.BibMark.EntryType;
/**
* The class reads the contents of a BibTeX file and makes it available as a map
* of ODF <code>BibMark</code> objects
*/
public class BibTeXReader {
private File file;
private String sEncoding;
private Map<String, BibMark> entries;
/** Construct a new <code>BibTeXReader</code> based on a file
*
* @param file the file to read
* @param sEncoding the character encoding of the file
* @throws IOException if any error occurs reading the file
* @throws ParseException if any error occurs interpreting the contents of the file
*/
public BibTeXReader(File file, String sEncoding) throws IOException, ParseException {
this.file = file;
this.sEncoding = sEncoding;
reload();
}
/** Parse the contents of the file, replacing any previous entries in this <code>BibTeXReader</code>
*/
public void reload() throws IOException, ParseException {
entries = new HashMap<String, BibMark>();
BibTeXDatabase database = parseBibTeX(file,sEncoding);
readEntries(database);
}
/** Get the file associated with this <code>BibTeXReader</code>
*
* @return the file
*/
public File getFile() {
return file;
}
/** Get the entries of this BibTeX file
*
* @return the entries
*/
public Map<String, BibMark> getEntries() {
return entries;
}
private static BibTeXDatabase parseBibTeX(File file, String sEncoding) throws ParseException, IOException {
FileInputStream is = new FileInputStream(file);
Reader reader = new InputStreamReader(is,sEncoding);
try {
BibTeXParser parser = new BibTeXParser() {
@Override
public void checkStringResolution(Key key, BibTeXString string) {
if (string == null) {
System.err.println("Unresolved string: \"" + key.getValue() + "\"");
}
}
@Override
public void checkCrossReferenceResolution(Key key,
BibTeXEntry entry) {
if (entry == null) {
System.err.println("Unresolved cross-reference: \"" + key.getValue() + "\"");
}
}
};
return parser.parse(reader);
} finally {
if (reader!=null) { reader.close(); }
if (is!=null) { is.close(); }
}
}
private void readEntries(BibTeXDatabase database) {
Map<Key, BibTeXEntry> entryMap = database.getEntries();
Collection<BibTeXEntry> bibentries = entryMap.values();
for (BibTeXEntry bibentry : bibentries) {
String sKey = bibentry.getKey().toString();
String sType = bibentry.getType().toString();
BibMark entry = new BibMark(sKey,sType);
entries.put(sKey, entry);
Map<Key,Value> fields = bibentry.getFields();
for (Key key : fields.keySet()) {
Value value = fields.get(key);
EntryType entryType = BibTeXEntryMap.getEntryType(key.getValue());
if (entryType!=null) {
entry.setField(entryType, parseLaTeX(value.toUserString()));
}
}
}
}
private static String parseLaTeX(String string) {
Reader reader = new StringReader(string);
try {
LaTeXParser parser = new LaTeXParser();
LaTeXPrinter printer = new LaTeXPrinter();
return printer.print(parser.parse(reader));
} catch (ParseException e) {
// If parsing fails, return the original string
return string;
} catch (TokenMgrException e) {
// If the string contains invalid characters, return the original string
return string;
} finally {
try {
reader.close();
} catch (IOException e) {
// Reading from a String will not fail :-)
}
}
}
}

View file

@ -0,0 +1,354 @@
/************************************************************************
*
* BibliographyDialog.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-07-23)
*
*/
package org.openoffice.da.comp.writer2latex;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import com.sun.star.awt.XContainerWindowEventHandler;
import com.sun.star.awt.XDialog;
import com.sun.star.awt.XWindow;
import com.sun.star.beans.XPropertySet;
import com.sun.star.frame.XDesktop;
import com.sun.star.frame.XModel;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.uno.AnyConverter;
import com.sun.star.uno.Exception;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.util.XChangesBatch;
import com.sun.star.lib.uno.helper.WeakBase;
import org.openoffice.da.comp.w2lcommon.helper.DialogAccess;
import org.openoffice.da.comp.w2lcommon.helper.FolderPicker;
import org.openoffice.da.comp.w2lcommon.helper.MessageBox;
import org.openoffice.da.comp.w2lcommon.helper.RegistryHelper;
import org.openoffice.da.comp.w2lcommon.helper.XPropertySetHelper;
/** This class provides a uno component which implements the configuration
* of the bibliography for the Writer2LaTeX toolbar
*/
public final class BibliographyDialog
extends WeakBase
implements XServiceInfo, XContainerWindowEventHandler {
public static final String REGISTRY_PATH = "/org.openoffice.da.Writer2LaTeX.toolbar.ToolbarOptions/BibliographyOptions"; //$NON-NLS-1$
private XComponentContext xContext;
private FolderPicker folderPicker;
/** The component will be registered under this name.
*/
public static String __serviceName = "org.openoffice.da.writer2latex.BibliographyDialog"; //$NON-NLS-1$
/** The component should also have an implementation name.
*/
public static String __implementationName = "org.openoffice.da.comp.writer2latex.BibliographyDialog"; //$NON-NLS-1$
/** Create a new ConfigurationDialog */
public BibliographyDialog(XComponentContext xContext) {
this.xContext = xContext;
folderPicker = new FolderPicker(xContext);
}
// Implement XContainerWindowEventHandler
public boolean callHandlerMethod(XWindow xWindow, Object event, String sMethod)
throws com.sun.star.lang.WrappedTargetException {
XDialog xDialog = (XDialog)UnoRuntime.queryInterface(XDialog.class, xWindow);
DialogAccess dlg = new DialogAccess(xDialog);
try {
if (sMethod.equals("external_event") ){ //$NON-NLS-1$
return handleExternalEvent(dlg, event);
}
else if (sMethod.equals("ConvertZoteroCitationsChange")) { //$NON-NLS-1$
return convertZoteroCitationsChange(dlg);
}
else if (sMethod.equals("ConvertJabRefCitationsChange")) { //$NON-NLS-1$
return convertJabRefCitationsChange(dlg);
}
else if (sMethod.equals("UseExternalBibTeXFilesChange")) { //$NON-NLS-1$
return useExternalBibTeXFilesChange(dlg);
}
else if (sMethod.equals("UseNatbibChange")) { //$NON-NLS-1$
return useNatbibChange(dlg);
}
else if (sMethod.equals("BibTeXLocationChange")) { //$NON-NLS-1$
return bibTeXLocationChange(dlg);
}
else if (sMethod.equals("BibTeXDirClick")) { //$NON-NLS-1$
return bibTeXDirClick(dlg);
}
}
catch (com.sun.star.uno.RuntimeException e) {
throw e;
}
catch (com.sun.star.uno.Exception e) {
throw new com.sun.star.lang.WrappedTargetException(sMethod, this, e);
}
return false;
}
public String[] getSupportedMethodNames() {
String[] sNames = { "external_event", "UseExternalBibTeXFilesChange", "ConvertZoteroCitationsChange", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
"ConvertJabRefCitationsChange", "UseNatbibChange", "BibTeXLocationChange", "ExternalBibTeXDirClick" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
return sNames;
}
// Implement the interface XServiceInfo
public boolean supportsService(String sServiceName) {
return sServiceName.equals(__serviceName);
}
public String getImplementationName() {
return __implementationName;
}
public String[] getSupportedServiceNames() {
String[] sSupportedServiceNames = { __serviceName };
return sSupportedServiceNames;
}
// Private stuff
private boolean handleExternalEvent(DialogAccess dlg, Object aEventObject)
throws com.sun.star.uno.Exception {
try {
String sMethod = AnyConverter.toString(aEventObject);
if (sMethod.equals("ok")) { //$NON-NLS-1$
saveConfiguration(dlg);
return true;
} else if (sMethod.equals("back") || sMethod.equals("initialize")) { //$NON-NLS-1$ //$NON-NLS-2$
loadConfiguration(dlg);
enableBibTeXSettings(dlg);
useNatbibChange(dlg);
return true;
}
}
catch (com.sun.star.lang.IllegalArgumentException e) {
throw new com.sun.star.lang.IllegalArgumentException(
"Method external_event requires a string in the event object argument.", this,(short) -1); //$NON-NLS-1$
}
return false;
}
// Load settings from the registry into the dialog
private void loadConfiguration(DialogAccess dlg) {
RegistryHelper registry = new RegistryHelper(xContext);
try {
Object view = registry.getRegistryView(REGISTRY_PATH, false);
XPropertySet xProps = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class,view);
dlg.setCheckBoxStateAsBoolean("UseExternalBibTeXFiles", //$NON-NLS-1$
XPropertySetHelper.getPropertyValueAsBoolean(xProps, "UseExternalBibTeXFiles")); //$NON-NLS-1$
dlg.setCheckBoxStateAsBoolean("ConvertZoteroCitations", //$NON-NLS-1$
XPropertySetHelper.getPropertyValueAsBoolean(xProps, "ConvertZoteroCitations")); //$NON-NLS-1$
dlg.setCheckBoxStateAsBoolean("ConvertJabRefCitations", //$NON-NLS-1$
XPropertySetHelper.getPropertyValueAsBoolean(xProps, "ConvertJabRefCitations")); //$NON-NLS-1$
dlg.setCheckBoxStateAsBoolean("IncludeOriginalCitations", //$NON-NLS-1$
XPropertySetHelper.getPropertyValueAsBoolean(xProps, "IncludeOriginalCitations")); //$NON-NLS-1$
dlg.setListBoxSelectedItem("BibTeXLocation", //$NON-NLS-1$
XPropertySetHelper.getPropertyValueAsShort(xProps, "BibTeXLocation")); //$NON-NLS-1$
dlg.setTextFieldText("BibTeXDir", //$NON-NLS-1$
XPropertySetHelper.getPropertyValueAsString(xProps, "BibTeXDir")); //$NON-NLS-1$
dlg.setListBoxSelectedItem("BibTeXEncoding", //$NON-NLS-1$
XPropertySetHelper.getPropertyValueAsShort(xProps, "BibTeXEncoding")); //$NON-NLS-1$
dlg.setCheckBoxStateAsBoolean("UseNatbib", //$NON-NLS-1$
XPropertySetHelper.getPropertyValueAsBoolean(xProps, "UseNatbib")); //$NON-NLS-1$
dlg.setTextFieldText("NatbibOptions", //$NON-NLS-1$
XPropertySetHelper.getPropertyValueAsString(xProps, "NatbibOptions")); //$NON-NLS-1$
registry.disposeRegistryView(view);
}
catch (Exception e) {
// Failed to get registry view
}
// Update dialog according to the settings
convertZoteroCitationsChange(dlg);
useExternalBibTeXFilesChange(dlg);
}
// Save settings from the dialog to the registry
private void saveConfiguration(DialogAccess dlg) {
RegistryHelper registry = new RegistryHelper(xContext);
try {
Object view = registry.getRegistryView(REGISTRY_PATH, true);
XPropertySet xProps = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class,view);
XPropertySetHelper.setPropertyValue(xProps, "UseExternalBibTeXFiles", dlg.getCheckBoxStateAsBoolean("UseExternalBibTeXFiles")); //$NON-NLS-1$ //$NON-NLS-2$
XPropertySetHelper.setPropertyValue(xProps, "ConvertZoteroCitations", dlg.getCheckBoxStateAsBoolean("ConvertZoteroCitations")); //$NON-NLS-1$ //$NON-NLS-2$
XPropertySetHelper.setPropertyValue(xProps, "ConvertJabRefCitations", dlg.getCheckBoxStateAsBoolean("ConvertJabRefCitations")); //$NON-NLS-1$ //$NON-NLS-2$
XPropertySetHelper.setPropertyValue(xProps, "IncludeOriginalCitations", dlg.getCheckBoxStateAsBoolean("IncludeOriginalCitations")); //$NON-NLS-1$ //$NON-NLS-2$
XPropertySetHelper.setPropertyValue(xProps, "BibTeXLocation", dlg.getListBoxSelectedItem("BibTeXLocation")); //$NON-NLS-1$ //$NON-NLS-2$
XPropertySetHelper.setPropertyValue(xProps, "BibTeXDir", dlg.getTextFieldText("BibTeXDir")); //$NON-NLS-1$ //$NON-NLS-2$
XPropertySetHelper.setPropertyValue(xProps, "BibTeXEncoding", dlg.getListBoxSelectedItem("BibTeXEncoding")); //$NON-NLS-1$ //$NON-NLS-2$
XPropertySetHelper.setPropertyValue(xProps, "UseNatbib", dlg.getCheckBoxStateAsBoolean("UseNatbib")); //$NON-NLS-1$ //$NON-NLS-2$
XPropertySetHelper.setPropertyValue(xProps, "NatbibOptions", dlg.getTextFieldText("NatbibOptions")); //$NON-NLS-1$ //$NON-NLS-2$
// Commit registry changes
XChangesBatch xUpdateContext = (XChangesBatch)
UnoRuntime.queryInterface(XChangesBatch.class,view);
try {
xUpdateContext.commitChanges();
}
catch (Exception e) {
// ignore
}
registry.disposeRegistryView(view);
}
catch (Exception e) {
// Failed to get registry view
}
}
private boolean useExternalBibTeXFilesChange(DialogAccess dlg) {
enableBibTeXSettings(dlg);
return true;
}
private boolean convertZoteroCitationsChange(DialogAccess dlg) {
enableBibTeXSettings(dlg);
return true;
}
private boolean convertJabRefCitationsChange(DialogAccess dlg) {
enableBibTeXSettings(dlg);
return true;
}
private boolean useNatbibChange(DialogAccess dlg) {
boolean bUseNatbib = dlg.getCheckBoxStateAsBoolean("UseNatbib"); //$NON-NLS-1$
dlg.setControlEnabled("NatbibOptionsLabel", bUseNatbib); //$NON-NLS-1$
dlg.setControlEnabled("NatbibOptions", bUseNatbib); //$NON-NLS-1$
return true;
}
private boolean bibTeXLocationChange(DialogAccess dlg) {
enableBibTeXSettings(dlg);
return true;
}
private void enableBibTeXSettings(DialogAccess dlg) {
boolean bEnableSettings = dlg.getCheckBoxStateAsBoolean("UseExternalBibTeXFiles"); //$NON-NLS-1$
boolean bEnableOriginalCitations = dlg.getCheckBoxStateAsBoolean("ConvertZoteroCitations") //$NON-NLS-1$
|| dlg.getCheckBoxStateAsBoolean("ConvertJabRefCitations"); //$NON-NLS-1$
boolean bEnableDir = dlg.getListBoxSelectedItem("BibTeXLocation")<2; //$NON-NLS-1$
dlg.setControlEnabled("BibTeXLocationLabel", bEnableSettings); //$NON-NLS-1$
dlg.setControlEnabled("BibTeXLocation", bEnableSettings); //$NON-NLS-1$
dlg.setControlEnabled("BibTeXDirLabel", bEnableSettings && bEnableDir); //$NON-NLS-1$
dlg.setControlEnabled("BibTeXDir", bEnableSettings && bEnableDir); //$NON-NLS-1$
dlg.setControlEnabled("BibTeXDirButton", bEnableSettings && bEnableDir); //$NON-NLS-1$
dlg.setControlEnabled("BibTeXEncodingLabel", bEnableSettings); //$NON-NLS-1$
dlg.setControlEnabled("BibTeXEncoding", bEnableSettings); //$NON-NLS-1$
dlg.setControlEnabled("ConvertZoteroCitations", bEnableSettings); //$NON-NLS-1$
dlg.setControlEnabled("ConvertJabRefCitations", bEnableSettings); //$NON-NLS-1$
dlg.setControlEnabled("IncludeOriginalCitations", bEnableSettings && bEnableOriginalCitations); //$NON-NLS-1$
}
private String getDocumentDirURL() {
// Get the desktop from the service manager
Object desktop=null;
try {
desktop = xContext.getServiceManager().createInstanceWithContext("com.sun.star.frame.Desktop", xContext); //$NON-NLS-1$
} catch (Exception e) {
// Failed to get the desktop service
return ""; //$NON-NLS-1$
}
XDesktop xDesktop = (XDesktop) UnoRuntime.queryInterface(XDesktop.class, desktop);
// Get the current component and verify that it really is a text document
if (xDesktop!=null) {
XComponent xComponent = xDesktop.getCurrentComponent();
XServiceInfo xInfo = (XServiceInfo)UnoRuntime.queryInterface(XServiceInfo.class, xComponent);
if (xInfo!=null && xInfo.supportsService("com.sun.star.text.TextDocument")) { //$NON-NLS-1$
// Get the model, which provides the URL
XModel xModel = (XModel) UnoRuntime.queryInterface(XModel.class, xComponent);
if (xModel!=null) {
String sURL = xModel.getURL();
int nSlash = sURL.lastIndexOf('/');
return nSlash>-1 ? sURL.substring(0, nSlash) : ""; //$NON-NLS-1$
}
}
}
return ""; //$NON-NLS-1$
}
private boolean hasBibTeXFiles(File dir) {
if (dir.isDirectory()) {
File[] files = dir.listFiles();
for (File file : files) {
if (file.isFile() && file.getName().endsWith(".bib")) { //$NON-NLS-1$
return true;
}
}
}
return false;
}
private boolean bibTeXDirClick(DialogAccess dlg) {
String sPath = folderPicker.getPath();
if (sPath!=null) {
try {
File bibDir = new File(new URI(sPath));
String sBibPath = bibDir.getCanonicalPath();
if (dlg.getListBoxSelectedItem("BibTeXLocation")==1) { //$NON-NLS-1$
// Path relative to document directory, remove the document directory part
String sDocumentDirURL = getDocumentDirURL();
if (sDocumentDirURL.length()>0) {
String sDocumentDirPath = new File(new URI(sDocumentDirURL)).getCanonicalPath();
if (sBibPath.startsWith(sDocumentDirPath)) {
if (sBibPath.length()>sDocumentDirPath.length()) {
sBibPath = sBibPath.substring(sDocumentDirPath.length()+1);
}
else { // Same as document directory
sBibPath = ""; //$NON-NLS-1$
}
}
else { // not a subdirectory
sBibPath = ""; //$NON-NLS-1$
}
}
}
dlg.setTextFieldText("BibTeXDir", sBibPath); //$NON-NLS-1$
if (!hasBibTeXFiles(bibDir)) {
MessageBox msgBox = new MessageBox(xContext);
msgBox.showMessage("Writer2LaTeX", Messages.getString("BibliographyDialog.nobibtexfiles")); //$NON-NLS-1$ //$NON-NLS-2$
}
}
catch (IOException e) {
}
catch (URISyntaxException e) {
}
}
return true;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,85 @@
/**
* CustomSymbolNameProvider.java
*
* Copyright: 2002-2009 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.2 (2009-11-09)
*
*/
package org.openoffice.da.comp.writer2latex;
import org.openoffice.da.comp.w2lcommon.helper.RegistryHelper;
import org.openoffice.da.comp.w2lcommon.helper.XPropertySetHelper;
import com.sun.star.beans.XPropertySet;
import com.sun.star.container.XNameAccess;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
/** This class provides access to the names of all user defined symbols in math
*
*/
public class CustomSymbolNameProvider {
Set<String> names;
/** Construct a new <code>CustomSymbolNameProvider</code>
*
* @param xContext the component context providing access to the api
*/
public CustomSymbolNameProvider(XComponentContext xContext) {
names = new HashSet<String>();
RegistryHelper registry = new RegistryHelper(xContext);
try {
// Prepare registry view
Object view = registry.getRegistryView("/org.openoffice.Office.Math/",false);
XPropertySet xProps = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class,view);
// Get the list of symbols
Object symbols = XPropertySetHelper.getPropertyValue(xProps,"SymbolList");
XNameAccess xSymbols = (XNameAccess) UnoRuntime.queryInterface(XNameAccess.class,symbols);
String[] sNames = xSymbols.getElementNames();
int nCount = sNames.length;
for (int i=0; i<nCount; i++) {
Object config = xSymbols.getByName(sNames[i]);
XPropertySet xSymbolProps = (XPropertySet)
UnoRuntime.queryInterface(XPropertySet.class,config);
if (!XPropertySetHelper.getPropertyValueAsBoolean(xSymbolProps,"Predefined")) {
names.add(sNames[i]);
}
}
}
catch (Exception e) {
// failed to get registry view, ignore
}
}
/** Return the names of all user defined symbols (excluding the predefined symbols such as ALPHA etc)
*
* @return a read only string set of symbols names
*/
public Set<String> getNames() {
return Collections.unmodifiableSet(names);
}
}

View file

@ -0,0 +1,220 @@
/************************************************************************
*
* DeTeXtive.java
*
* Copyright: 2002-2014 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.4 (2014-09-24)
*
*/
package org.openoffice.da.comp.writer2latex;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.HashSet;
import org.openoffice.da.comp.w2lcommon.tex.tokenizer.Mouth;
import org.openoffice.da.comp.w2lcommon.tex.tokenizer.Token;
import org.openoffice.da.comp.w2lcommon.tex.tokenizer.TokenType;
/** This class analyzes a stream and detects if it is a TeX stream.
* Currently it is able to identify LaTeX and XeLaTeX (ConTeXt and plain TeX may be
* added later).
*/
public class DeTeXtive {
private Mouth mouth;
private Token token;
private HashSet<String> packages;
/** Construct a new DeTeXtive
*/
public DeTeXtive() {
}
/** Detect the format of a given stream
*
* @param is the input stream
* @return a string representing the detected format; null if the format is unknown.
* Currently the values "LaTeX", "XeLaTeX" are supported.
* @throws IOException if we fail to read the stream
*/
public String deTeXt(InputStream is) throws IOException {
// It makes no harm to assume that the stream uses ISO Latin1 - we only consider ASCII characters
mouth = new Mouth(new InputStreamReader(is,"ISO8859_1"));
token = mouth.getTokenObject();
packages = new HashSet<String>();
mouth.getToken();
if (parseHeader() && parsePreamble()) {
if (packages.contains("xunicode")) {
return "XeLaTeX";
}
else {
return "LaTeX";
}
}
// Unknown format
return null;
}
// The parser!
// Parse a LaTeX header such as \documentclass[a4paper]{article}
// Return true in case of success
private boolean parseHeader() throws IOException {
skipBlanks();
if (token.isCS("documentclass") || token.isCS("documentstyle")) {
// The first non-blank token is \documentclass or \documentstyle => could be a LaTeX document
//System.out.println("** Found "+token.toString());
mouth.getToken();
skipSpaces();
// Skip options, if any
if (token.is('[',TokenType.OTHER)) {
skipOptional();
skipSpaces();
}
if (token.getType()==TokenType.BEGIN_GROUP) {
// Get class name
String sClassName = parseArgumentAsString();
//System.out.println("** Found the class name "+sClassName);
// Accept any class name of one or more characters
if (sClassName.length()>0) { return true; }
}
}
//System.out.println("** Doesn't look like LaTeX; failed to get class name");
return false;
}
// Parse a LaTeX preamble
// Return true in case of success (that is, \begin{document} was found)
private boolean parsePreamble() throws IOException {
while (token.getType()!=TokenType.ENDINPUT) {
if (token.isCS("usepackage")) {
// We collect the names of all used packages, but discard their options
// (Recall that this is only relevant for LaTeX 2e)
mouth.getToken();
skipSpaces();
if (token.is('[',TokenType.OTHER)) {
skipOptional();
skipSpaces();
}
String sName = parseArgumentAsString();
//System.out.println("** Found package "+sName);
packages.add(sName);
}
else if (token.getType()==TokenType.BEGIN_GROUP) {
// We ignore anything inside a group
skipGroup();
}
else if (token.isCS("begin")) {
// This would usually indicate the end of the preamble
mouth.getToken();
skipSpaces();
if ("document".equals(parseArgumentAsString())) {
//System.out.println("Found \\begin{document}");
return true;
}
}
else {
// Any other content in the preamble is simply ignored
mouth.getToken();
}
}
//System.out.println("** Doesn't look like LaTeX; failed to find \\begin{document}");
return false;
}
private void skipBlanks() throws IOException {
while (token.getType()==TokenType.SPACE || token.isCS("par")) {
mouth.getToken();
}
}
private void skipSpaces() throws IOException {
// Actually, we will never get two space tokens in a row
while (token.getType()==TokenType.SPACE) {
mouth.getToken();
}
}
private void skipOptional() throws IOException {
assert token.is('[', TokenType.OTHER);
mouth.getToken(); // skip the [
while (!token.is(']',TokenType.OTHER) && token.getType()!=TokenType.ENDINPUT) {
if (token.getType()==TokenType.BEGIN_GROUP) {
skipGroup();
}
else {
mouth.getToken(); // skip this token
}
}
mouth.getToken(); // skip the ]
}
private void skipGroup() throws IOException {
assert token.getType()==TokenType.BEGIN_GROUP;
mouth.getToken(); // skip the {
while (token.getType()!=TokenType.END_GROUP && token.getType()!=TokenType.ENDINPUT) {
if (token.getType()==TokenType.BEGIN_GROUP) {
skipGroup();
}
else {
mouth.getToken(); // skip this token
}
}
mouth.getToken(); // skip the }
}
private String parseArgumentAsString() throws IOException {
if (token.getType()==TokenType.BEGIN_GROUP) {
// Argument is contained in a group
mouth.getToken(); // skip the {
StringBuilder sb = new StringBuilder();
while (token.getType()!=TokenType.END_GROUP && token.getType()!=TokenType.ENDINPUT) {
if (token.getType()!=TokenType.COMMAND_SEQUENCE) {
// should not include cs, ignore if it happens
sb.append(token.getChar());
}
mouth.getToken();
}
mouth.getToken(); // skip the }
return sb.toString();
}
else {
// Argument is a single token
String s = "";
if (token.getType()!=TokenType.COMMAND_SEQUENCE) {
// should not include cs, ignore if it happens
s = token.getString();
}
mouth.getToken();
return s;
}
}
}

View file

@ -0,0 +1,341 @@
/************************************************************************
*
* ExternalApps.java
*
* Copyright: 2002-2018 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2018-03-06)
*
*/
package org.openoffice.da.comp.writer2latex;
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.lang.Process;
import java.lang.ProcessBuilder;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import org.openoffice.da.comp.w2lcommon.helper.RegistryHelper;
import org.openoffice.da.comp.w2lcommon.helper.StreamGobbler;
import org.openoffice.da.comp.w2lcommon.helper.XPropertySetHelper;
import com.sun.star.beans.XMultiHierarchicalPropertySet;
import com.sun.star.beans.XPropertySet;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.util.XChangesBatch;
/** This class manages and executes external applications used by the Writer2LaTeX toolbar.
* These include TeX and friends as well as viewers for the various backend formats.
* The registry is used for persistent storage of the settings.
*/
public class ExternalApps {
public final static short EXPORT = (short)0;
public final static short BUILD = (short)1;
public final static short PREVIEW = (short)2;
public final static String LATEX = "LaTeX"; //$NON-NLS-1$
public final static String PDFLATEX = "PdfLaTeX"; //$NON-NLS-1$
public final static String XELATEX = "XeLaTeX"; //$NON-NLS-1$
public final static String BIBTEX = "BibTeX"; //$NON-NLS-1$
public final static String MAKEINDEX = "Makeindex"; //$NON-NLS-1$
public final static String MK4HT = "Mk4ht"; //$NON-NLS-1$
public final static String DVIPS = "Dvips"; //$NON-NLS-1$
public final static String DVIVIEWER = "DVIViewer"; //$NON-NLS-1$
public final static String POSTSCRIPTVIEWER = "PostscriptViewer"; //$NON-NLS-1$
public final static String PDFVIEWER = "PdfViewer"; //$NON-NLS-1$
private final static String[] sApps = { LATEX, PDFLATEX, XELATEX, BIBTEX, MAKEINDEX, MK4HT, DVIPS, DVIVIEWER, POSTSCRIPTVIEWER, PDFVIEWER };
private XComponentContext xContext;
private short nLevel = (short)2;
private Map<String,String[]> apps;
private Set<String> defaultApps;
/** Construct a new ExternalApps object with empty content */
public ExternalApps(XComponentContext xContext) {
this.xContext = xContext;
apps = new HashMap<String,String[]>();
defaultApps = new HashSet<String>();
for (int i=0; i<sApps.length; i++) {
setApplication(sApps[i], "", ""); //$NON-NLS-1$ //$NON-NLS-2$
setUseDefaultApplication(sApps[i],true);
}
}
/** Return the localized name for an external app to use in the UI (only the viewers has a separate UI name)
*
* @param sName the app name
* @return the UI name
*/
public static String getUIAppName(String sName) {
if (DVIVIEWER.equals(sName)) {
return Messages.getString("ExternalApps.dviviewer"); //$NON-NLS-1$
}
else if (PDFVIEWER.equals(sName)) {
return Messages.getString("ExternalApps.pdfviewer"); //$NON-NLS-1$
}
else if (POSTSCRIPTVIEWER.equals(sName)) {
return Messages.getString("ExternalApps.psviewer"); //$NON-NLS-1$
}
return sName;
}
/** Set the desired processing level (0: export only, 1: export and build, 2: export, build and preview)
*
* @param nLevel the desired level
*/
public void setProcessingLevel(short nLevel) {
this.nLevel = nLevel;
}
/** Get the desired processing level (0: export only, 1: export and build, 2: export, build and preview)
*
* @return the level
*/
public short getProcessingLevel() {
return nLevel;
}
public boolean isViewer(String sAppName) {
return sAppName!=null && sAppName.endsWith("Viewer"); //$NON-NLS-1$
}
/** Define an external application
* @param sAppName the name of the application to define
* @param sExecutable the system dependent path to the executable file
* @param sOptions the options to the external application; %s will be
* replaced by the filename on execution
*/
public void setApplication(String sAppName, String sExecutable, String sOptions) {
String[] sValue = { sExecutable, sOptions };
apps.put(sAppName, sValue);
}
/** Get the definition for an external application
* @param sAppName the name of the application to get
* @return a String array containing the system dependent path to the
* executable file as entry 0 and the parameters as entry 1
* returns null if the application is unknown
*/
public String[] getApplication(String sAppName) {
return apps.get(sAppName);
}
/** Define to use the system's default for an external application. This is only possible if the application is a viewer,
* otherwise setting the value to true will be ignored
* @param sAppName the name of the application
* @param bUseDefault flag defining whether or not to use the default
*/
public void setUseDefaultApplication(String sAppName, boolean bUseDefault) {
if (bUseDefault && isViewer(sAppName)) {
defaultApps.add(sAppName);
}
else if (defaultApps.contains(sAppName)) {
defaultApps.remove(sAppName);
}
}
/** Get the setting to use the system's default application
*
* @param sAppName the name of the application
* @return true if the system's default should be used, false if not or if the application is unknown
*/
public boolean getUseDefaultApplication(String sAppName) {
return defaultApps.contains(sAppName);
}
/** Execute an external application
* @param sAppName the name of the application to execute (ignored for default apps)
* @param sFileName the file name to use
* @param workDir the working directory to use
* @param env map of environment variables to set (or null if no variables needs to be set, ignored for default apps)
* @param bWaitFor true if the method should wait for the execution to finish (ignored for default apps)
* @return error code
*/
public int execute(String sAppName, String sFileName, File workDir, Map<String,String> env, boolean bWaitFor) {
if (defaultApps.contains(sAppName)) {
return openWithDefaultApplication(new File(sFileName)) ? 0 : 1;
}
else {
return execute(sAppName, "", sFileName, workDir, env, bWaitFor); //$NON-NLS-1$
}
}
// Open the file in the default application on this system (if any)
private boolean openWithDefaultApplication(File file) {
if (Desktop.isDesktopSupported()) {
Desktop desktop = Desktop.getDesktop();
try {
desktop.open(file);
return true;
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
return false;
}
/** Execute an external application
* @param sAppName the name of the application to execute
* @param sCommand subcommand/option to pass to the command
* @param sFileName the file name to use
* @param workDir the working directory to use
* @param env map of environment variables to set (or null if no variables needs to be set)
* @param bWaitFor true if the method should wait for the execution to finish
* @return error code
*/
public int execute(String sAppName, String sCommand, String sFileName, File workDir, Map<String,String> env, boolean bWaitFor) {
// Assemble the command
String[] sApp = getApplication(sAppName);
if (sApp==null) { return 1; }
try {
Vector<String> command = new Vector<String>();
command.add(sApp[0]);
String[] sArguments = sApp[1].split(" "); //$NON-NLS-1$
for (String s : sArguments) {
command.add(s.replace("%c",sCommand).replace("%s",sFileName)); //$NON-NLS-1$ //$NON-NLS-2$
}
ProcessBuilder pb = new ProcessBuilder(command);
pb.directory(workDir);
if (env!=null) {
pb.environment().putAll(env);
}
Process proc = pb.start();
// Gobble the error stream of the application
StreamGobbler errorGobbler = new
StreamGobbler(proc.getErrorStream(), "ERROR"); //$NON-NLS-1$
// Gobble the output stream of the application
StreamGobbler outputGobbler = new
StreamGobbler(proc.getInputStream(), "OUTPUT"); //$NON-NLS-1$
// Kick them off
errorGobbler.start();
outputGobbler.start();
// Any error?
return bWaitFor ? proc.waitFor() : 0;
}
catch (InterruptedException e) {
return 1;
}
catch (IOException e) {
return 1;
}
}
/** Load the external applications from the registry
*/
public void load() {
RegistryHelper registry = new RegistryHelper(xContext);
Object view;
try {
// Prepare registry view
view = registry.getRegistryView("/org.openoffice.da.Writer2LaTeX.toolbar.ToolbarOptions/Applications",false); //$NON-NLS-1$
}
catch (com.sun.star.uno.Exception e) {
// Give up...
return;
}
XPropertySet xSimpleProps = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class,view);
nLevel = XPropertySetHelper.getPropertyValueAsShort(xSimpleProps,"AfterExport"); //$NON-NLS-1$
XMultiHierarchicalPropertySet xProps = (XMultiHierarchicalPropertySet)
UnoRuntime.queryInterface(XMultiHierarchicalPropertySet.class, view);
for (int i=0; i<sApps.length; i++) {
String[] sNames = new String[3];
sNames[0] = sApps[i]+"/Executable"; //$NON-NLS-1$
sNames[1] = sApps[i]+"/Options"; //$NON-NLS-1$
sNames[2] = sApps[i]+"/UseDefault"; //$NON-NLS-1$
try {
Object[] values = xProps.getHierarchicalPropertyValues(sNames);
setApplication(sApps[i], (String) values[0], (String) values[1]);
setUseDefaultApplication(sApps[i], ((Boolean) values[2]).booleanValue());
}
catch (com.sun.star.uno.Exception e) {
// Ignore...
}
}
registry.disposeRegistryView(view);
}
/** Save the external applications to the registry
*/
public void save() {
RegistryHelper registry = new RegistryHelper(xContext);
Object view;
try {
view = registry.getRegistryView("/org.openoffice.da.Writer2LaTeX.toolbar.ToolbarOptions/Applications",true); //$NON-NLS-1$
}
catch (com.sun.star.uno.Exception e) {
// Give up...
return;
}
XPropertySet xSimpleProps = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class,view);
XPropertySetHelper.setPropertyValue(xSimpleProps, "AfterExport", nLevel); //$NON-NLS-1$
XMultiHierarchicalPropertySet xProps = (XMultiHierarchicalPropertySet)
UnoRuntime.queryInterface(XMultiHierarchicalPropertySet.class, view);
for (int i=0; i<sApps.length; i++) {
String[] sNames = new String[3];
sNames[0] = sApps[i]+"/Executable"; //$NON-NLS-1$
sNames[1] = sApps[i]+"/Options"; //$NON-NLS-1$
sNames[2] = sApps[i]+"/UseDefault"; //$NON-NLS-1$
String[] sApp = getApplication(sApps[i]);
boolean bUseDefault = getUseDefaultApplication(sApps[i]);
Object[] values = { sApp[0], sApp[1], new Boolean(bUseDefault) };
try {
xProps.setHierarchicalPropertyValues(sNames, values);
}
catch (com.sun.star.uno.Exception e) {
// Ignore...
}
}
// Commit registry changes
XChangesBatch xUpdateContext = (XChangesBatch)
UnoRuntime.queryInterface(XChangesBatch.class, view);
try {
xUpdateContext.commitChanges();
}
catch (Exception e) {
// ignore
}
registry.disposeRegistryView(view);
}
}

View file

@ -0,0 +1,385 @@
/************************************************************************
*
* LaTeXOptionsDialog.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-05-12)
*
*/
package org.openoffice.da.comp.writer2latex;
import com.sun.star.awt.XDialog;
import com.sun.star.beans.XPropertySet;
import com.sun.star.uno.XComponentContext;
import org.openoffice.da.comp.w2lcommon.helper.PropertyHelper;
import org.openoffice.da.comp.w2lcommon.filter.OptionsDialogBase;
/** This class provides a UNO component which implements a filter ui for the
* LaTeX export
*/
public class LaTeXOptionsDialog extends OptionsDialogBase {
// Translate list box items to configuration option values
private static final String[] BACKEND_VALUES =
{ "generic", "pdftex", "dvips", "xetex", "unspecified" };
private static final String[] INPUTENCODING_VALUES =
{ "ascii", "latin1", "latin2", "iso-8859-7", "cp1250", "cp1251", "koi8-r", "utf8" };
private static final String[] NOTES_VALUES =
{ "ignore", "comment", "marginpar", "pdfannotation" };
private static final String[] FLOATOPTIONS_VALUES =
{ "", "tp", "bp", "htp", "hbp" };
// UI names and configuration option values for fonts
private static final String[] FONT_VALUES =
{ "default", "cmbright", "ccfonts", "ccfonts-euler",
"iwona", "kurier", "anttor", "kmath-kerkis",
"fouriernc",
"pxfonts", "mathpazo", "mathpple",
"txfonts", "mathptmx",
"arev",
"charter-mathdesign", "utopia-mathdesign", "fourier" };
private static final String[] FONT_NAMES =
{ "Default (Computer Modern)", "CM Bright", "Concrete", "Concrete + Euler Math",
"Iwona", "Kurier", "Antykwa Toru\u0144ska", "Kerkis",
"New Century Schoolbook + Fourier Math",
"Palatino + PXfonts Math", "Palatino + Pazo Math", "Palatino + Euler Math",
"Times + TXfonts Math", "Times + Symbol",
"Arev Sans + Arev Math",
"Bitstream Charter + Math Design", "Utopia + Math Design", "Utopia + Fourier Math" };
/** The component will be registered under this name.
*/
public static String __serviceName = "org.openoffice.da.writer2latex.LaTeXOptionsDialog";
/** The component should also have an implementation name.
* The subclass should override this with a suitable name
*/
public static String __implementationName = "org.openoffice.da.comp.writer2latex.LaTeXOptionsDialog";
public String getDialogLibraryName() { return "W2LDialogs"; }
/** Create a new LaTeXOptionsDialog */
public LaTeXOptionsDialog(XComponentContext xContext) {
super(xContext);
xMSF = W2LRegistration.xMultiServiceFactory;
}
/** Return the name of the dialog within the library
*/
public String getDialogName() { return "LaTeXOptions"; }
/** Return the name of the registry path
*/
public String getRegistryPath() {
return "/org.openoffice.da.Writer2LaTeX.Options/LaTeXOptions";
}
/** Load settings from the registry to the dialog */
protected void loadSettings(XPropertySet xProps) {
// General
loadConfig(xProps);
loadListBoxOption(xProps,"Backend");
loadListBoxOption(xProps,"Inputencoding");
loadCheckBoxOption(xProps,"Multilingual");
setListBoxStringItemList("Font", FONT_NAMES);
loadListBoxOption(xProps,"Font");
loadCheckBoxOption(xProps,"GreekMath");
loadCheckBoxOption(xProps,"AdditionalSymbols");
// Bibliography
loadCheckBoxOption(xProps,"UseBibtex");
loadComboBoxOption(xProps,"BibtexStyle");
// Files
loadCheckBoxOption(xProps,"WrapLines");
loadNumericOption(xProps,"WrapLinesAfter");
loadCheckBoxOption(xProps,"SplitLinkedSections");
loadCheckBoxOption(xProps,"SplitToplevelSections");
loadCheckBoxOption(xProps,"SaveImagesInSubdir");
// Special content
loadListBoxOption(xProps,"Notes");
loadCheckBoxOption(xProps,"Metadata");
loadCheckBoxOption(xProps,"DisplayHiddenText");
// Figures and tables
loadCheckBoxOption(xProps,"OriginalImageSize");
loadCheckBoxOption(xProps,"OptimizeSimpleTables");
loadNumericOption(xProps,"SimpleTableLimit");
loadCheckBoxOption(xProps,"FloatTables");
loadCheckBoxOption(xProps,"FloatFigures");
loadListBoxOption(xProps,"FloatOptions");
// AutoCorrect
loadCheckBoxOption(xProps,"IgnoreHardPageBreaks");
loadCheckBoxOption(xProps,"IgnoreHardLineBreaks");
loadCheckBoxOption(xProps,"IgnoreEmptyParagraphs");
loadCheckBoxOption(xProps,"IgnoreDoubleSpaces");
updateLockedOptions();
enableControls();
}
/** Save settings from the dialog to the registry and create FilterData */
protected void saveSettings(XPropertySet xProps, PropertyHelper filterData) {
// General
short nConfig = saveConfig(xProps, filterData);
switch (nConfig) {
case 0: filterData.put("ConfigURL","*ultraclean.xml"); break;
case 1: filterData.put("ConfigURL","*clean.xml"); break;
case 2: filterData.put("ConfigURL","*default.xml"); break;
case 3: filterData.put("ConfigURL","*pdfprint.xml"); break;
case 4: filterData.put("ConfigURL","*pdfscreen.xml"); break;
case 5: filterData.put("ConfigURL","$(user)/writer2latex.xml");
filterData.put("AutoCreate","true");
}
saveListBoxOption(xProps, filterData, "Backend", "backend", BACKEND_VALUES );
if (getListBoxSelectedItem("Config")==4) {
// pdfscreen locks the backend to pdftex
filterData.put("backend","pdftex");
}
saveListBoxOption(xProps, filterData, "Inputencoding", "inputencoding", INPUTENCODING_VALUES);
saveCheckBoxOption(xProps, filterData, "Multilingual", "multilingual");
saveListBoxOption(xProps, filterData, "Font", "font", FONT_VALUES);
saveCheckBoxOption(xProps, filterData, "GreekMath", "greek_math");
// AdditionalSymbols sets 5 different w2l options...
saveCheckBoxOption(xProps, filterData, "AdditionalSymbols", "use_pifont");
saveCheckBoxOption(xProps, filterData, "AdditionalSymbols", "use_ifsym");
saveCheckBoxOption(xProps, filterData, "AdditionalSymbols", "use_wasysym");
saveCheckBoxOption(xProps, filterData, "AdditionalSymbols", "use_eurosym");
saveCheckBoxOption(xProps, filterData, "AdditionalSymbols", "use_tipa");
// Bibliography
saveCheckBoxOption(xProps, filterData, "UseBibtex", "use_bibtex");
saveComboBoxOption(xProps, filterData, "BibtexStyle", "bibtex_style");
// Files
boolean bWrapLines = saveCheckBoxOption(xProps, "WrapLines");
int nWrapLinesAfter = saveNumericOption(xProps, "WrapLinesAfter");
if (!isLocked("wrap_lines_after")) {
if (bWrapLines) {
filterData.put("wrap_lines_after",Integer.toString(nWrapLinesAfter));
}
else {
filterData.put("wrap_lines_after","0");
}
}
saveCheckBoxOption(xProps, filterData, "SplitLinkedSections", "split_linked_sections");
saveCheckBoxOption(xProps, filterData, "SplitToplevelSections", "split_toplevel_sections");
saveCheckBoxOption(xProps, filterData, "SaveImagesInSubdir", "save_images_in_subdir");
// Special content
saveListBoxOption(xProps, filterData, "Notes", "notes", NOTES_VALUES);
saveCheckBoxOption(xProps, filterData, "Metadata", "metadata");
saveCheckBoxOption(xProps, filterData, "DisplayHiddenText", "display_hidden_text");
// Figures and tables
saveCheckBoxOption(xProps, filterData, "OriginalImageSize", "original_image_size");
boolean bOptimizeSimpleTables = saveCheckBoxOption(xProps,"OptimizeSimpleTables");
int nSimpleTableLimit = saveNumericOption(xProps,"SimpleTableLimit");
if (!isLocked("simple_table_limit")) {
if (bOptimizeSimpleTables) {
filterData.put("simple_table_limit",Integer.toString(nSimpleTableLimit));
}
else {
filterData.put("simple_table_limit","0");
}
}
saveCheckBoxOption(xProps, filterData, "FloatTables", "float_tables");
saveCheckBoxOption(xProps, filterData, "FloatFigures", "float_figures");
saveListBoxOption(xProps, filterData, "FloatOptions", "float_options", FLOATOPTIONS_VALUES);
// AutoCorrect
saveCheckBoxOption(xProps, filterData, "IgnoreHardPageBreaks", "ignore_hard_page_breaks");
saveCheckBoxOption(xProps, filterData, "IgnoreHardLineBreaks", "ignore_hard_line_breaks");
saveCheckBoxOption(xProps, filterData, "IgnoreEmptyParagraphs", "ignore_empty_paragraphs");
saveCheckBoxOption(xProps, filterData, "IgnoreDoubleSpaces", "ignore_double_spaces");
}
// Implement XDialogEventHandler
public boolean callHandlerMethod(XDialog xDialog, Object event, String sMethod) {
if (sMethod.equals("ConfigChange") || sMethod.equals("BackendChange")) {
updateLockedOptions();
enableControls();
}
else if (sMethod.equals("UseBibtexChange")) {
enableBibtexStyle();
}
else if (sMethod.equals("WrapLinesChange")) {
enableWrapLinesAfter();
}
else if (sMethod.equals("OptimizeSimpleTablesChange")) {
enableSimpleTableLimit();
}
else if (sMethod.equals("FloatTablesChange")) {
enableFloatOptions();
}
else if (sMethod.equals("FloatFiguresChange")) {
enableFloatOptions();
}
return true;
}
public String[] getSupportedMethodNames() {
String[] sNames = { "ConfigChange", "UseBibtexChange", "WrapLinesChange",
"OptimizeSimpleTablesChange", "FloatTablesChange", "FloatFiguresChange" };
return sNames;
}
protected boolean isLocked(String sOptionName) {
if ("backend".equals(sOptionName)) {
// backend must be pdf for pdfscreen
return getListBoxSelectedItem("Config")==4 || super.isLocked(sOptionName);
}
else if ("inputencoding".equals(sOptionName)) {
// backend=xetex locks the encoding to utf8
return getListBoxSelectedItem("Backend")==3 || super.isLocked(sOptionName);
}
else if ("font".equals(sOptionName)) {
// backend=xetex does not (currently) use the font option
return getListBoxSelectedItem("Backend")==3 || super.isLocked(sOptionName);
}
else if ("greek_math".equals(sOptionName)) {
// this option has no effect if backend=xetex
return getListBoxSelectedItem("Backend")==3 || super.isLocked(sOptionName);
}
else if ("additional_symbols".equals(sOptionName)) {
// additional_symbols is disabled for custom config (where the 5
// individual options can be set independently)
// it is also disabled for backend=xetex
return getListBoxSelectedItem("Backend")==3 || getListBoxSelectedItem("Config")==5 || super.isLocked(sOptionName);
}
else if ("use_pifont".equals(sOptionName)) {
return isLocked("additional_symbols");
}
else if ("use_ifsym".equals(sOptionName)) {
return isLocked("additional_symbols");
}
else if ("use_wasysym".equals(sOptionName)) {
return isLocked("additional_symbols");
}
else if ("use_eurosym".equals(sOptionName)) {
return isLocked("additional_symbols");
}
else if ("use_tipa".equals(sOptionName)) {
return isLocked("additional_symbols");
}
else {
return super.isLocked(sOptionName);
}
}
private void enableControls() {
// General
setControlEnabled("BackendLabel",!isLocked("backend"));
setControlEnabled("Backend",!isLocked("backend"));
setControlEnabled("InputencodingLabel",!isLocked("inputencoding"));
setControlEnabled("Inputencoding",!isLocked("inputencoding"));
setControlEnabled("Multilingual",!isLocked("multilingual"));
setControlEnabled("FontLabel",!isLocked("font"));
setControlEnabled("Font",!isLocked("font"));
setControlEnabled("GreekMath",!isLocked("greek_math"));
setControlEnabled("AdditionalSymbols",!isLocked("additional_symbols"));
// Bibliography
setControlEnabled("UseBibtex",!isLocked("use_bibtex"));
boolean bUseBibtex = getCheckBoxStateAsBoolean("UseBibtex");
setControlEnabled("BibtexStyleLabel",!isLocked("bibtex_style") && bUseBibtex);
setControlEnabled("BibtexStyle",!isLocked("bibtex_style") && bUseBibtex);
// Files
setControlEnabled("WrapLines",!isLocked("wrap_lines_after"));
boolean bWrapLines = getCheckBoxStateAsBoolean("WrapLines");
setControlEnabled("WrapLinesAfterLabel",!isLocked("wrap_lines_after") && bWrapLines);
setControlEnabled("WrapLinesAfter",!isLocked("wrap_lines_after") && bWrapLines);
setControlEnabled("SplitLinkedSections",!isLocked("split_linked_sections"));
setControlEnabled("SplitToplevelSections",!isLocked("split_toplevel_sections"));
setControlEnabled("SaveImagesInSubdir",!isLocked("save_images_in_subdir"));
// Special content
setControlEnabled("NotesLabel",!isLocked("notes"));
setControlEnabled("Notes",!isLocked("notes"));
setControlEnabled("Metadata",!isLocked("metadata"));
setControlEnabled("DisplayHiddenText",!isLocked("display_hidden_text"));
// Figures and tables
setControlEnabled("OriginalImageSize",!isLocked("original_image_size"));
setControlEnabled("OptimizeSimpleTables",!isLocked("simple_table_limit"));
boolean bOptimizeSimpleTables = getCheckBoxStateAsBoolean("OptimizeSimpleTables");
setControlEnabled("SimpleTableLimitLabel",!isLocked("simple_table_limit") && bOptimizeSimpleTables);
setControlEnabled("SimpleTableLimit",!isLocked("simple_table_limit") && bOptimizeSimpleTables);
setControlEnabled("FloatTables",!isLocked("float_tables"));
setControlEnabled("FloatFigures",!isLocked("float_figures"));
boolean bFloat = getCheckBoxStateAsBoolean("FloatFigures") ||
getCheckBoxStateAsBoolean("FloatTables");
setControlEnabled("FloatOptionsLabel",!isLocked("float_options") && bFloat);
setControlEnabled("FloatOptions",!isLocked("float_options") && bFloat);
// AutoCorrect
setControlEnabled("IgnoreHardPageBreaks",!isLocked("ignore_hard_page_breaks"));
setControlEnabled("IgnoreHardLineBreaks",!isLocked("ignore_hard_line_breaks"));
setControlEnabled("IgnoreEmptyParagraphs",!isLocked("ignore_empty_paragraphs"));
setControlEnabled("IgnoreDoubleSpaces",!isLocked("ignore_double_spaces"));
}
private void enableBibtexStyle() {
if (!isLocked("bibtex_style")) {
boolean bState = getCheckBoxStateAsBoolean("UseBibtex");
setControlEnabled("BibtexStyleLabel",bState);
setControlEnabled("BibtexStyle",bState);
}
}
private void enableWrapLinesAfter() {
if (!isLocked("wrap_lines_after")) {
boolean bState = getCheckBoxStateAsBoolean("WrapLines");
setControlEnabled("WrapLinesAfterLabel",bState);
setControlEnabled("WrapLinesAfter",bState);
}
}
private void enableSimpleTableLimit() {
if (!isLocked("simple_table_limit")) {
boolean bState = getCheckBoxStateAsBoolean("OptimizeSimpleTables");
setControlEnabled("SimpleTableLimitLabel",bState);
setControlEnabled("SimpleTableLimit",bState);
}
}
private void enableFloatOptions() {
if (!isLocked("float_options")) {
boolean bState = getCheckBoxStateAsBoolean("FloatFigures") ||
getCheckBoxStateAsBoolean("FloatTables");
setControlEnabled("FloatOptionsLabel",bState);
setControlEnabled("FloatOptions",bState);
}
}
}

View file

@ -0,0 +1,207 @@
/************************************************************************
*
* LaTeXUNOPublisher.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-07-23)
*
*/
package org.openoffice.da.comp.writer2latex;
import java.io.File;
import java.io.IOException;
import org.openoffice.da.comp.w2lcommon.filter.UNOPublisher;
import org.openoffice.da.comp.w2lcommon.helper.MessageBox;
import org.openoffice.da.comp.w2lcommon.helper.PropertyHelper;
import org.openoffice.da.comp.w2lcommon.helper.RegistryHelper;
import org.openoffice.da.comp.w2lcommon.helper.XPropertySetHelper;
import writer2latex.latex.i18n.ClassicI18n;
import writer2latex.util.CSVList;
import writer2latex.util.Misc;
import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.XPropertySet;
import com.sun.star.frame.XFrame;
import com.sun.star.uno.Exception;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
public class LaTeXUNOPublisher extends UNOPublisher {
// The TeXifier and associated data
private TeXify texify = null;
private String sBibinputs=null;
private String sBackend = "generic"; //$NON-NLS-1$
public LaTeXUNOPublisher(XComponentContext xContext, XFrame xFrame, String sAppName) {
super(xContext, xFrame, sAppName);
}
/** Get the directory containing the BibTeX files (as defined in the registry)
*
* @return the directory
*/
public File getBibTeXDirectory() {
// Get the BibTeX settings from the registry
RegistryHelper registry = new RegistryHelper(xContext);
Object view;
try {
view = registry.getRegistryView(BibliographyDialog.REGISTRY_PATH, false);
} catch (Exception e) {
// Failed to get registry settings
return null;
}
XPropertySet xProps = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class,view);
return getDirectory(XPropertySetHelper.getPropertyValueAsShort(xProps, "BibTeXLocation"), //$NON-NLS-1$
XPropertySetHelper.getPropertyValueAsString(xProps, "BibTeXDir")); //$NON-NLS-1$
}
/** Make a file name LaTeX friendly
*/
@Override protected String filterFileName(String sFileName) {
return Misc.makeTeXFriendly(sFileName,"writer2latex"); //$NON-NLS-1$
}
/** Post process the filter data: Set bibliography options and
* determine the backend and the BIBINPUTS directory
*/
@Override protected PropertyValue[] postProcessMediaProps(PropertyValue[] mediaProps) {
sBackend = "generic"; //$NON-NLS-1$
sBibinputs = null;
PropertyHelper mediaHelper = new PropertyHelper(mediaProps);
Object filterData = mediaHelper.get("FilterData"); //$NON-NLS-1$
if (filterData instanceof PropertyValue[]) {
PropertyHelper filterHelper = new PropertyHelper((PropertyValue[])filterData);
// Get the backend
Object backend = filterHelper.get("backend"); //$NON-NLS-1$
if (backend instanceof String) {
sBackend = (String) backend;
}
// Set the bibliography options according to the settings
RegistryHelper registry = new RegistryHelper(xContext);
try {
Object view = registry.getRegistryView(BibliographyDialog.REGISTRY_PATH, false);
XPropertySet xProps = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class,view);
String sBibTeXFiles = getFileList(XPropertySetHelper.getPropertyValueAsShort(xProps, "BibTeXLocation"), //$NON-NLS-1$
XPropertySetHelper.getPropertyValueAsString(xProps, "BibTeXDir")); //$NON-NLS-1$
if (XPropertySetHelper.getPropertyValueAsBoolean(xProps, "UseExternalBibTeXFiles")) { //$NON-NLS-1$
filterHelper.put("external_bibtex_files", sBibTeXFiles); //$NON-NLS-1$
filterHelper.put("bibtex_encoding", ClassicI18n.writeInputenc( //$NON-NLS-1$
XPropertySetHelper.getPropertyValueAsShort(xProps, "BibTeXEncoding"))); //$NON-NLS-1$
if (XPropertySetHelper.getPropertyValueAsBoolean(xProps, "ConvertZoteroCitations")) { //$NON-NLS-1$
filterHelper.put("zotero_bibtex_files", sBibTeXFiles); //$NON-NLS-1$
}
if (XPropertySetHelper.getPropertyValueAsBoolean(xProps, "ConvertJabRefCitations")) { //$NON-NLS-1$
filterHelper.put("jabref_bibtex_files", sBibTeXFiles); //$NON-NLS-1$
}
}
filterHelper.put("include_original_citations", //$NON-NLS-1$
Boolean.toString(XPropertySetHelper.getPropertyValueAsBoolean(xProps, "IncludeOriginalCitations"))); //$NON-NLS-1$
String sBibTeXDir = XPropertySetHelper.getPropertyValueAsString(xProps, "BibTeXDir"); //$NON-NLS-1$
if (sBibTeXDir.length()>0) {
// The separator character in BIBINPUTS is OS specific
sBibinputs = sBibTeXDir+File.pathSeparatorChar;
}
filterHelper.put("use_natbib", Boolean.toString(XPropertySetHelper.getPropertyValueAsBoolean(xProps, "UseNatbib"))); //$NON-NLS-1$ //$NON-NLS-2$
filterHelper.put("natbib_options", XPropertySetHelper.getPropertyValueAsString(xProps, "NatbibOptions")); //$NON-NLS-1$ //$NON-NLS-2$
mediaHelper.put("FilterData",filterHelper.toArray()); //$NON-NLS-1$
PropertyValue[] newMediaProps = mediaHelper.toArray();
registry.disposeRegistryView(view);
return newMediaProps;
}
catch (Exception e) {
// Failed to get registry view; return original media props
return mediaProps;
}
}
// No filter data; return original media props
return mediaProps;
}
/** Postprocess the converted document with LaTeX and display the result
*/
@Override protected void postProcess(String sURL, TargetFormat format) {
if (texify==null) { texify = new TeXify(xContext); }
File file = new File(Misc.urlToFile(getTargetPath()),getTargetFileName());
boolean bResult = true;
try {
if (sBackend=="pdftex") { //$NON-NLS-1$
bResult = texify.process(file, sBibinputs, TeXify.PDFTEX, true);
}
else if (sBackend=="dvips") { //$NON-NLS-1$
bResult = texify.process(file, sBibinputs, TeXify.DVIPS, true);
}
else if (sBackend=="xetex") { //$NON-NLS-1$
bResult = texify.process(file, sBibinputs, TeXify.XETEX, true);
}
else if (sBackend=="generic") { //$NON-NLS-1$
bResult = texify.process(file, sBibinputs, TeXify.GENERIC, true);
}
}
catch (IOException e) {
MessageBox msgBox = new MessageBox(xContext, xFrame);
msgBox.showMessage("Writer2LaTeX",Messages.getString("LaTeXUNOPublisher.error")+": "+e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
}
if (!bResult) {
MessageBox msgBox = new MessageBox(xContext, xFrame);
msgBox.showMessage("Writer2LaTeX",Messages.getString("LaTeXUNOPublisher.error")+": "+Messages.getString("LaTeXUNOPublisher.failedlatex")); //$NON-NLS-1$ //$NON-NLS-2$
}
}
private File getDirectory(short nType, String sDirectory) {
switch (nType) {
case 0: // absolute path
return new File(sDirectory);
case 1: // relative path
return new File(Misc.urlToFile(getTargetPath()),sDirectory);
default: // document directory
return Misc.urlToFile(getTargetPath());
}
}
private String getFileList(short nType, String sDirectory) {
File dir = getDirectory(nType,sDirectory);
File[] files;
if (dir.isDirectory()) {
files = dir.listFiles();
}
else {
return null;
}
CSVList filelist = new CSVList(","); //$NON-NLS-1$
if (files!=null) {
for (File file : files) {
if (file.isFile() && file.getName().endsWith(".bib")) { //$NON-NLS-1$
filelist.addValue(Misc.removeExtension(file.getName()));
}
}
}
return filelist.toString();
}
}

View file

@ -0,0 +1,182 @@
/************************************************************************
*
* LogViewerDialog.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-02-10)
*
*/
package org.openoffice.da.comp.writer2latex;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import com.sun.star.awt.XDialog;
import com.sun.star.uno.XComponentContext;
import org.openoffice.da.comp.w2lcommon.helper.DialogAccess;
import org.openoffice.da.comp.w2lcommon.helper.DialogBase;
/** This class provides a uno component which displays logfiles
*/
public class LogViewerDialog extends DialogBase
implements com.sun.star.lang.XInitialization {
/** The component will be registered under this name.
*/
public static String __serviceName = "org.openoffice.da.writer2latex.LogViewerDialog";
/** The component should also have an implementation name.
*/
public static String __implementationName = "org.openoffice.da.comp.writer2latex.LogViewerDialog";
/** Return the name of the library containing the dialog
*/
public String getDialogLibraryName() {
return "W2LDialogs2";
}
private String sBaseUrl = null;
private String sLaTeXLog = null;
private String sLaTeXErrors = null;
private String sBibTeXLog = null;
private String sMakeindexLog = null;
/** Return the name of the dialog within the library
*/
public String getDialogName() {
return "LogViewer";
}
public void initialize() {
if (sBaseUrl!=null) {
sLaTeXLog = readTextFile(sBaseUrl+".log");
sLaTeXErrors = errorFilter(sLaTeXLog);
sBibTeXLog = readTextFile(sBaseUrl+".blg");
sMakeindexLog = readTextFile(sBaseUrl+".ilg");
setComboBoxText("LogContents",sLaTeXLog);
}
}
public void endDialog() {
}
/** Create a new LogViewerDialog */
public LogViewerDialog(XComponentContext xContext) {
super(xContext);
}
// Implement com.sun.star.lang.XInitialization
public void initialize( Object[] object )
throws com.sun.star.uno.Exception {
if ( object.length > 0 ) {
if (object[0] instanceof String) {
sBaseUrl = (String) object[0];
}
}
}
// Implement XDialogEventHandler
public boolean callHandlerMethod(XDialog xDialog, Object event, String sMethod) {
if (sMethod.equals("ViewLaTeXLog")) {
setComboBoxText("LogContents",
getCheckBoxState("ErrorFilter")==DialogAccess.CHECKBOX_CHECKED ? sLaTeXErrors : sLaTeXLog);
setControlEnabled("ErrorFilter",true);
}
else if (sMethod.equals("ViewBibTeXLog")) {
setComboBoxText("LogContents", sBibTeXLog);
setControlEnabled("ErrorFilter",false);
}
else if (sMethod.equals("ViewMakeindexLog")) {
setComboBoxText("LogContents", sMakeindexLog);
setControlEnabled("ErrorFilter",false);
}
else if (sMethod.equals("ErrorFilterChange")) {
setComboBoxText("LogContents",
getCheckBoxState("ErrorFilter")==DialogAccess.CHECKBOX_CHECKED ? sLaTeXErrors : sLaTeXLog);
}
return true;
}
public String[] getSupportedMethodNames() {
String[] sNames = { "ViewLaTeXLog", "ViewBibTeXLog", "ViewMakeindexLog", "ErrorFilterChange" };
return sNames;
}
// Utility methods
private String readTextFile(String sUrl) {
StringBuilder buf = new StringBuilder();
try {
File file = new File(new URI(sUrl));
if (file.exists() && file.isFile()) {
InputStreamReader isr = new InputStreamReader(new FileInputStream(file));
int n;
do {
n = isr.read();
if (n>-1) { buf.append((char)n); }
}
while (n>-1);
isr.close();
}
}
catch (URISyntaxException e) {
return "";
}
catch (IOException e) {
return "";
}
return buf.toString();
}
// Extract errors from LaTeX log file only
private String errorFilter(String log) {
StringBuilder buf = new StringBuilder();
int nLen = log.length();
int nIndex = 0;
boolean bIncludeLines = false;
while (nIndex<nLen) {
int nNewline = log.indexOf('\n', nIndex);
if (nNewline==-1) nNewline = nLen;
if (nNewline-nIndex>1 && log.charAt(nIndex)=='!') {
bIncludeLines = true;
}
else if (nNewline==nIndex) {
if (bIncludeLines) {
buf.append('\n');
}
bIncludeLines = false;
}
if (bIncludeLines) {
buf.append(log.substring(nIndex,nNewline)).append('\n');
}
nIndex = nNewline+1;
}
return buf.toString();
}
}

View file

@ -0,0 +1,46 @@
/************************************************************************
*
* Messages.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-05-29)
*
*/
package org.openoffice.da.comp.writer2latex;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
public class Messages {
private static final String BUNDLE_NAME = "org.openoffice.da.comp.writer2latex.messages"; //$NON-NLS-1$
private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
.getBundle(BUNDLE_NAME);
private Messages() {
}
public static String getString(String key) {
try {
return RESOURCE_BUNDLE.getString(key);
} catch (MissingResourceException e) {
return '!' + key + '!';
}
}
}

View file

@ -0,0 +1,173 @@
/************************************************************************
*
* TeXDetectService.java
*
* Copyright: 2002-2014 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2014-10-29)
*
*/
package org.openoffice.da.comp.writer2latex;
import java.io.IOException;
import com.sun.star.lib.uno.adapter.XInputStreamToInputStreamAdapter;
import com.sun.star.lib.uno.helper.WeakBase;
import com.sun.star.beans.PropertyValue;
import com.sun.star.document.XExtendedFilterDetection;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.io.XInputStream;
import com.sun.star.ucb.XSimpleFileAccess2;
import com.sun.star.uno.AnyConverter;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
/** This class provides detect services for TeX documents
* It is thus an implementation of the service com.sun.star.document.ExtendedTypeDetection
*/
public class TeXDetectService extends WeakBase implements XExtendedFilterDetection, XServiceInfo {
// Constants
// Identify this service
public static final String __implementationName = TeXDetectService.class.getName();
public static final String __serviceName = "com.sun.star.document.ExtendedTypeDetection";
private static final String[] m_serviceNames = { __serviceName };
// The type names
private static final String LATEX_FILE = "org.openoffice.da.writer2latex.LaTeX_File";
private static final String XELATEX_FILE = "org.openoffice.da.writer2latex.XeLaTeX_File";
// From constructor+initialization
private final XComponentContext m_xContext;
/** Construct a new <code>TeXDetectService</code>
*
* @param xContext The Component Context
*/
public TeXDetectService( XComponentContext xContext ) {
m_xContext = xContext;
}
// Implement 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;
}
// Implement XExtendedFilterDetection
public String detect(PropertyValue[][] mediaDescriptor) {
// Read the media properties
String sURL = null;
String sTypeName = null;
if (mediaDescriptor.length>0) {
int nLength = mediaDescriptor[0].length;
for (int i=0; i<nLength; i++) {
try {
if (mediaDescriptor[0][i].Name.equals("URL")) {
sURL = AnyConverter.toString(mediaDescriptor[0][i].Value);
}
else if (mediaDescriptor[0][i].Name.equals("TypeName")) {
sTypeName = AnyConverter.toString(mediaDescriptor[0][i].Value);
}
}
catch (com.sun.star.lang.IllegalArgumentException e) {
// AnyConverter failed to convert; ignore this
}
}
}
// If there's no URL, we cannot verify the type (this should never happen on proper use of the service)
if (sURL==null) {
return "";
}
// Also, we can only verify LaTeX and XeLaTeX
if (sTypeName==null || !(sTypeName.equals(LATEX_FILE) || sTypeName.equals(XELATEX_FILE))) {
return "";
}
// Initialise the file access
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)
return "";
}
// Get the input stream
XInputStreamToInputStreamAdapter is = null;
try {
XInputStream xis = sfa2.openFileRead(sURL);
is = new XInputStreamToInputStreamAdapter(xis);
}
catch (com.sun.star.ucb.CommandAbortedException e) {
// Failed to create input stream, cannot verify the type
return "";
}
catch (com.sun.star.uno.Exception e) {
// Failed to create input stream, cannot verify the type
return "";
}
// Ask the deTeXtive
DeTeXtive deTeXtive = new DeTeXtive();
try {
String sType = deTeXtive.deTeXt(is);
if ("LaTeX".equals(sType)) {
return LATEX_FILE;
}
else if ("XeLaTeX".equals(sType)) {
return XELATEX_FILE;
}
else {
return "";
}
}
catch (IOException e) {
// Failed to read the stream, cannot verify the type
return "";
}
}
}

View file

@ -0,0 +1,339 @@
/************************************************************************
*
* TeXImportFilter.java
*
* Copyright: 2002-2014 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2014-10-29)
*
*/
package org.openoffice.da.comp.writer2latex;
//import com.sun.star.lib.uno.helper.Factory;
import java.io.File;
import java.net.URI;
import com.sun.star.lib.uno.helper.WeakBase;
import com.sun.star.document.XDocumentInsertable;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.task.XStatusIndicator;
import com.sun.star.text.XTextCursor;
import com.sun.star.text.XTextDocument;
import com.sun.star.uno.XComponentContext;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.AnyConverter;
import com.sun.star.beans.PropertyValue;
import com.sun.star.lang.XInitialization;
import com.sun.star.container.XNamed;
import com.sun.star.document.XImporter;
import com.sun.star.document.XFilter;
/** This class implements an import filter for TeX documents using TeX4ht
* It is thus an implementation of the service com.sun.star.document.ImportFilter
*/
public class TeXImportFilter extends WeakBase implements XInitialization, XNamed, XImporter, XFilter, XServiceInfo {
// Constants
// Identify this service
public static final String __implementationName = TeXImportFilter.class.getName();
public static final String __serviceName = "com.sun.star.document.ImportFilter";
private static final String[] m_serviceNames = { __serviceName };
// Possible states of the filtering process
public static final int FILTERPROC_RUNNING = 0;
public static final int FILTERPROC_BREAKING = 1;
public static final int FILTERPROC_STOPPED = 2;
// Global data
// From constructor
private final XComponentContext m_xContext;
// The filter name
private String m_sFilterName;
// The target document for the import
private com.sun.star.text.XTextDocument m_xTargetDoc;
// The current state of the filtering process
private int m_nState;
/** Construct a new <code>TeXImportFilter</code>
*
* @param xContext The Component Context
*/
public TeXImportFilter( XComponentContext xContext ) {
m_xContext = xContext;
m_sFilterName = "";
m_xTargetDoc = null;
m_nState = FILTERPROC_STOPPED;
}
// Implement 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;
}
// The following methods may be called from multiple threads (e.g. if someone wants to cancel the filtering),
// thus all access to class members must be synchronized
// Implement XInitialization:
public void initialize( Object[] arguments ) throws com.sun.star.uno.Exception {
if (arguments.length>0) {
// The first argument contains configuration data, from which we extract the filter name for further reference
// We need this to know which flavour of TeX we're supposed to handle
PropertyValue[] config = (PropertyValue[]) arguments[0];
int nLen = config.length;
for (int i=0; i<nLen; i++) {
if (config[i].Name.equals("Name")) {
synchronized(this) {
try {
m_sFilterName = AnyConverter.toString(config[i].Value);
}
catch(com.sun.star.lang.IllegalArgumentException exConvert) {
// ignore
}
}
}
}
}
}
// Implement XNamed
public String getName() {
synchronized(this) {
return m_sFilterName;
}
}
public void setName( String sName ) {
// must be ignored as we cannot change the filter name
}
// Implement XImporter
public void setTargetDocument( com.sun.star.lang.XComponent xDocument ) throws com.sun.star.lang.IllegalArgumentException {
// If there's no target document we cannot import into it
if (xDocument==null)
throw new com.sun.star.lang.IllegalArgumentException("Null pointer");
// And if it's not a text document we're out of luck too
com.sun.star.lang.XServiceInfo xInfo = (com.sun.star.lang.XServiceInfo)UnoRuntime.queryInterface(
com.sun.star.lang.XServiceInfo.class, xDocument);
if (!xInfo.supportsService("com.sun.star.text.TextDocument"))
throw new com.sun.star.lang.IllegalArgumentException("Wrong document type");
// Otherwise set the target document
synchronized(this) {
m_xTargetDoc = (com.sun.star.text.XTextDocument)UnoRuntime.queryInterface(
com.sun.star.text.XTextDocument.class, xDocument);
}
}
// Implement XFilter:
/** Filter (import only) the document given by the media descriptor
* According to the service contract, we should understand either of
* the properties URL or InputStream, but currently we only use the former.
* We also use the property StatusIndicator: OOo internally uses this to
* pass around an XStatusIndicator instance, and if it's available we
* use it to display a progress bar
*
* @param mediaDescriptor the Media Descriptor
*/
public boolean filter(com.sun.star.beans.PropertyValue[] mediaDescriptor) {
// Extract values from the MediaDescriptor
String sURL = null;
XStatusIndicator xStatusIndicator = null;
int nLength = mediaDescriptor.length;
for (int i=0; i<nLength; i++) {
try {
if (mediaDescriptor[i].Name.equals("URL")) {
sURL = AnyConverter.toString(mediaDescriptor[i].Value);
}
else if (mediaDescriptor[i].Name.equals("InputStream")) {
// Ignore this currently
}
else if (mediaDescriptor[i].Name.equals("StatusIndicator")) {
xStatusIndicator = (XStatusIndicator) AnyConverter.toObject(XStatusIndicator.class, mediaDescriptor[i].Value);
}
}
catch (com.sun.star.lang.IllegalArgumentException e) {
// AnyConverter failed to convert; ignore this
}
}
if (sURL==null) {
// Currently we need and URL to import
return false;
}
// Copy the current value of the target document and mark the filtering process as running
XTextDocument xText = null;
synchronized(this) {
if (m_nState!=FILTERPROC_STOPPED) {
return false;
}
xText = m_xTargetDoc;
m_nState = FILTERPROC_RUNNING;
}
// Do the import
boolean bResult = importTeX(xText,sURL,xStatusIndicator);
m_nState = FILTERPROC_STOPPED;
return bResult;
}
/** Cancel the filtering process. This will not only trigger cancellation, but also wait until it's finished
*/
public void cancel() {
// Change state to "breaking"
synchronized(this) {
if (m_nState==FILTERPROC_RUNNING) m_nState=FILTERPROC_BREAKING;
}
// And wait until state has changed to "stopped"
while (true) {
synchronized(this) {
if (m_nState==FILTERPROC_STOPPED)
break;
}
}
}
// Private helper methods
/** Import a TeX document with TeX4ht
* @param xText into this document
* @param sURL from the TeX document given by this URL
*/
public boolean importTeX(XTextDocument xText, String sURL, XStatusIndicator xStatus) {
int nStep = 0;
if (xStatus!=null) {
xStatus.start("Writer2LaTeX",10);
xStatus.setValue(++nStep);
}
// Get the LaTeX file
File file = null;
try {
file = new File(new URI(sURL));
}
catch (java.net.URISyntaxException e) {
// Could not use the URL provided
if (xStatus!=null) xStatus.end();
return false;
}
if (xStatus!=null) { xStatus.setValue(++nStep); }
// Protect the ODT file if it already exists
String sBaseName = file.getName();
if (sBaseName.endsWith(".tex")) { sBaseName = sBaseName.substring(0, sBaseName.length()-4); }
File odtFile = new File(file.getParentFile(),sBaseName+".odt");
File tempFile = null;
if (odtFile.exists()) {
try {
tempFile = File.createTempFile("w2l", ".tmp", file.getParentFile());
}
catch (java.io.IOException e) {
// Failed to protect the ODT file, give up
if (xStatus!=null) xStatus.end();
return false;
}
odtFile.renameTo(tempFile);
}
if (xStatus!=null) { xStatus.setValue(++nStep); }
// Execute TeX4ht
ExternalApps externalApps = new ExternalApps(m_xContext);
externalApps.load();
if (xStatus!=null) { xStatus.setValue(++nStep); }
// Default is the filter org.openoffice.da.writer2latex.latex
String sCommand = "oolatex";
if ("org.openoffice.da.writer2latex.xelatex".equals(m_sFilterName)) {
sCommand = "ooxelatex";
}
externalApps.execute(ExternalApps.MK4HT, sCommand, file.getName(), file.getParentFile(), null, true);
if (xStatus!=null) { nStep+=5; xStatus.setValue(nStep); }
// Assemble the URL of the ODT file
String sODTURL = sURL;
if (sODTURL.endsWith(".tex")) { sODTURL = sODTURL.substring(0, sODTURL.length()-4); }
sODTURL += ".odt";
// This is the only good time to test if we should cancel the import
boolean bSuccess = true;
synchronized(this) {
if (m_nState==FILTERPROC_BREAKING) bSuccess = false;
}
if (xStatus!=null) {
xStatus.end();
}
if (bSuccess) {
// Load ODT file into the text document
XTextCursor xTextCursor = xText.getText().createTextCursor();
XDocumentInsertable xDocInsert = (XDocumentInsertable)
UnoRuntime.queryInterface(XDocumentInsertable.class, xTextCursor);
try {
PropertyValue[] props = new PropertyValue[0];
xDocInsert.insertDocumentFromURL(sODTURL, props);
}
catch (com.sun.star.lang.IllegalArgumentException e) {
bSuccess = false;
}
catch (com.sun.star.io.IOException e) {
bSuccess = false;
}
}
odtFile.delete();
// Restore origninal ODT file, if any
if (tempFile!=null) {
tempFile.renameTo(odtFile);
}
return bSuccess;
}
}

View file

@ -0,0 +1,162 @@
/************************************************************************
*
* TeXify.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-05-29)
*
*/
package org.openoffice.da.comp.writer2latex;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import com.sun.star.uno.XComponentContext;
/** This class builds LaTeX documents into DVI, Postscript or PDF and displays
* the result.
*/
public final class TeXify {
/** Backend format generic (dvi) */
public static final short GENERIC = 1;
/** Backend format dvips (postscript) */
public static final short DVIPS = 2;
/** Backend format pdfTeX (pdf) */
public static final short PDFTEX = 3;
/** Backend format XeTeX (also pdf, usually) */
public static final short XETEX = 4;
// Define the applications to run for each backend
private static final String[] genericTexify = {
ExternalApps.LATEX, ExternalApps.BIBTEX, ExternalApps.MAKEINDEX,
ExternalApps.LATEX, ExternalApps.MAKEINDEX, ExternalApps.LATEX };
private static final String[] pdfTexify = {
ExternalApps.PDFLATEX, ExternalApps.BIBTEX, ExternalApps.MAKEINDEX,
ExternalApps.PDFLATEX, ExternalApps.MAKEINDEX, ExternalApps.PDFLATEX };
private static final String[] dvipsTexify = {
ExternalApps.LATEX, ExternalApps.BIBTEX, ExternalApps.MAKEINDEX,
ExternalApps.LATEX, ExternalApps.MAKEINDEX, ExternalApps.LATEX,
ExternalApps.DVIPS };
private static final String[] xeTexify = {
ExternalApps.XELATEX, ExternalApps.BIBTEX, ExternalApps.MAKEINDEX,
ExternalApps.XELATEX, ExternalApps.MAKEINDEX, ExternalApps.XELATEX };
// Global objects
private ExternalApps externalApps;
public TeXify(XComponentContext xContext) {
externalApps = new ExternalApps(xContext);
}
/** Process a document. This will either (depending on the registry settings) do nothing, build with LaTeX
* or build with LaTeX and preview
*
* @param file the LaTeX file to process
* @param sBibinputs value for the BIBINPUTS environment variable (or null if it should not be extended)
* @param nBackend the desired backend format (generic, dvips, pdftex)
* @param bView set the true if the result should be displayed in the viewer
* @throws IOException if the document cannot be read
* @return true if the first LaTeX run was successful
*/
public boolean process(File file, String sBibinputs, short nBackend, boolean bView) throws IOException {
// Remove extension from file
if (file.getName().endsWith(".tex")) { //$NON-NLS-1$
file = new File(file.getParentFile(),
file.getName().substring(0,file.getName().length()-4));
}
// Update external apps from registry
externalApps.load();
// Process LaTeX document
if (externalApps.getProcessingLevel()>=ExternalApps.BUILD) {
boolean bPreview = externalApps.getProcessingLevel()>=ExternalApps.PREVIEW;
boolean bResult = false;
if (nBackend==GENERIC) {
bResult = doTeXify(genericTexify, file, sBibinputs);
if (!bResult) return false;
if (bPreview && externalApps.execute(ExternalApps.DVIVIEWER,
new File(file.getParentFile(),file.getName()+".dvi").getPath(), //$NON-NLS-1$
file.getParentFile(), null, false)>0) {
throw new IOException(Messages.getString("TeXify.dviviewerror")); //$NON-NLS-1$
}
}
else if (nBackend==PDFTEX) {
bResult = doTeXify(pdfTexify, file, sBibinputs);
if (!bResult) return false;
if (bPreview && externalApps.execute(ExternalApps.PDFVIEWER,
new File(file.getParentFile(),file.getName()+".pdf").getPath(), //$NON-NLS-1$
file.getParentFile(), null, false)>0) {
throw new IOException(Messages.getString("TeXify.pdfviewerror")); //$NON-NLS-1$
}
}
else if (nBackend==DVIPS) {
bResult = doTeXify(dvipsTexify, file, sBibinputs);
if (!bResult) return false;
if (bPreview && externalApps.execute(ExternalApps.POSTSCRIPTVIEWER,
new File(file.getParentFile(),file.getName()+".ps").getPath(), //$NON-NLS-1$
file.getParentFile(), null, false)>0) {
throw new IOException(Messages.getString("TeXify.psviewerror")); //$NON-NLS-1$
}
}
else if (nBackend==XETEX) {
bResult = doTeXify(xeTexify, file, sBibinputs);
if (!bResult) return false;
if (bPreview && externalApps.execute(ExternalApps.PDFVIEWER,
new File(file.getParentFile(),file.getName()+".pdf").getPath(), //$NON-NLS-1$
file.getParentFile(), null, false)>0) {
throw new IOException(Messages.getString("TeXify.pdfviewerror")); //$NON-NLS-1$
}
}
return bResult;
}
return true;
}
private boolean doTeXify(String[] sAppList, File file, String sBibinputs) throws IOException {
// Remove the .aux file first (to avoid potential error messages)
File aux = new File(file.getParentFile(), file.getName()+".aux"); //$NON-NLS-1$
aux.delete();
for (int i=0; i<sAppList.length; i++) {
// Execute external application
Map<String,String> env =null;
if (ExternalApps.BIBTEX.equals(sAppList[i]) && sBibinputs!=null) {
env = new HashMap<String,String>();
env.put("BIBINPUTS", sBibinputs); //$NON-NLS-1$
}
int nReturnCode = externalApps.execute(
sAppList[i], file.getName(), file.getParentFile(), env, true);
if (i==0 && nReturnCode>0) {
return false;
//throw new IOException("Error executing "+sAppList[i]);
}
}
return true;
}
}

View file

@ -0,0 +1,54 @@
/************************************************************************
*
* W2LExportFilter.java
*
* Copyright: 2002-2014 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2014-10-06)
*
*/
package org.openoffice.da.comp.writer2latex;
import com.sun.star.uno.XComponentContext;
import org.openoffice.da.comp.w2lcommon.filter.ExportFilterBase;
/** This class implements the LaTeX and BibTeX export filter component
*/
public class W2LExportFilter extends ExportFilterBase {
/** Service name for the component */
public static final String __serviceName = "org.openoffice.da.comp.writer2latex.W2LExportFilter";
/** Implementation name for the component */
public static final String __implementationName = "org.openoffice.da.comp.writer2latex.W2LExportFilter";
/** Filter name to include in error messages */
public final String __displayName = "Writer2LaTeX";
public W2LExportFilter(XComponentContext xComponentContext1) {
super(xComponentContext1);
}
}

View file

@ -0,0 +1,165 @@
/************************************************************************
*
* W2LRegistration.java
*
* Copyright: 2002-2014 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2014-12-11)
*
*/
package org.openoffice.da.comp.writer2latex;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.lang.XSingleServiceFactory;
import com.sun.star.registry.XRegistryKey;
import com.sun.star.comp.loader.FactoryHelper;
/** This class provides a static method to instantiate our uno components
* on demand (__getServiceFactory()), and a static method to give
* information about the components (__writeRegistryServiceInfo()).
* Furthermore, it saves the XMultiServiceFactory provided to the
* __getServiceFactory method for future reference by the componentes.
*/
public class W2LRegistration {
public static XMultiServiceFactory xMultiServiceFactory;
/**
* Returns a factory for creating the service.
* This method is called by the <code>JavaLoader</code>
*
* @return returns a <code>XSingleServiceFactory</code> for creating the
* component
*
* @param implName the name of the implementation for which a
* service is desired
* @param multiFactory the service manager to be used if needed
* @param regKey the registryKey
*
* @see com.sun.star.comp.loader.JavaLoader
*/
public static XSingleServiceFactory __getServiceFactory(String implName,
XMultiServiceFactory multiFactory, XRegistryKey regKey) {
xMultiServiceFactory = multiFactory;
XSingleServiceFactory xSingleServiceFactory = null;
if (implName.equals(W2LExportFilter.class.getName()) ) {
xSingleServiceFactory = FactoryHelper.getServiceFactory(W2LExportFilter.class,
W2LExportFilter.__serviceName,
multiFactory,
regKey);
}
else if (implName.equals(LaTeXOptionsDialog.__implementationName)) {
xSingleServiceFactory = FactoryHelper.getServiceFactory(LaTeXOptionsDialog.class,
LaTeXOptionsDialog.__serviceName,
multiFactory,
regKey);
}
else if (implName.equals(W2LStarMathConverter.__implementationName)) {
xSingleServiceFactory = FactoryHelper.getServiceFactory(W2LStarMathConverter.class,
W2LStarMathConverter.__serviceName,
multiFactory,
regKey);
}
else if (implName.equals(ConfigurationDialog.__implementationName)) {
xSingleServiceFactory = FactoryHelper.getServiceFactory(ConfigurationDialog.class,
ConfigurationDialog.__serviceName,
multiFactory,
regKey);
}
else if (implName.equals(Writer2LaTeX.__implementationName) ) {
xSingleServiceFactory = FactoryHelper.getServiceFactory(Writer2LaTeX.class,
Writer2LaTeX.__serviceName,
multiFactory,
regKey);
}
else if (implName.equals(TeXImportFilter.__implementationName) ) {
xSingleServiceFactory = FactoryHelper.getServiceFactory(TeXImportFilter.class,
TeXImportFilter.__serviceName,
multiFactory,
regKey);
}
else if (implName.equals(TeXDetectService.__implementationName) ) {
xSingleServiceFactory = FactoryHelper.getServiceFactory(TeXDetectService.class,
TeXDetectService.__serviceName,
multiFactory,
regKey);
}
else if (implName.equals(ApplicationsDialog.__implementationName) ) {
xSingleServiceFactory = FactoryHelper.getServiceFactory(ApplicationsDialog.class,
ApplicationsDialog.__serviceName,
multiFactory,
regKey);
}
else if (implName.equals(BibliographyDialog.__implementationName) ) {
xSingleServiceFactory = FactoryHelper.getServiceFactory(BibliographyDialog.class,
BibliographyDialog.__serviceName,
multiFactory,
regKey);
}
else if (implName.equals(LogViewerDialog.__implementationName) ) {
xSingleServiceFactory = FactoryHelper.getServiceFactory(LogViewerDialog.class,
LogViewerDialog.__serviceName,
multiFactory,
regKey);
}
else if (implName.equals(BibTeXDialog.__implementationName) ) {
xSingleServiceFactory = FactoryHelper.getServiceFactory(BibTeXDialog.class,
BibTeXDialog.__serviceName,
multiFactory,
regKey);
}
return xSingleServiceFactory;
}
/**
* Writes the service information into the given registry key.
* This method is called by the <code>JavaLoader</code>
* <p>
* @return returns true if the operation succeeded
* @param regKey the registryKey
* @see com.sun.star.comp.loader.JavaLoader
*/
public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) {
return
FactoryHelper.writeRegistryServiceInfo(W2LExportFilter.__implementationName,
W2LExportFilter.__serviceName, regKey) &
FactoryHelper.writeRegistryServiceInfo(LaTeXOptionsDialog.__implementationName,
LaTeXOptionsDialog.__serviceName, regKey) &
FactoryHelper.writeRegistryServiceInfo(W2LStarMathConverter.__implementationName,
W2LStarMathConverter.__serviceName, regKey) &
FactoryHelper.writeRegistryServiceInfo(ConfigurationDialog.__implementationName,
ConfigurationDialog.__serviceName, regKey) &
FactoryHelper.writeRegistryServiceInfo(Writer2LaTeX.__implementationName,
Writer2LaTeX.__serviceName, regKey) &
FactoryHelper.writeRegistryServiceInfo(TeXImportFilter.__implementationName,
TeXImportFilter.__serviceName, regKey) &
FactoryHelper.writeRegistryServiceInfo(TeXDetectService.__implementationName,
TeXDetectService.__serviceName, regKey) &
FactoryHelper.writeRegistryServiceInfo(ApplicationsDialog.__implementationName,
ApplicationsDialog.__serviceName, regKey) &
FactoryHelper.writeRegistryServiceInfo(BibliographyDialog.__implementationName,
BibliographyDialog.__serviceName, regKey) &
FactoryHelper.writeRegistryServiceInfo(LogViewerDialog.__implementationName,
LogViewerDialog.__serviceName, regKey) &
FactoryHelper.writeRegistryServiceInfo(BibTeXDialog.__implementationName,
BibTeXDialog.__serviceName, regKey);
}
}

View file

@ -0,0 +1,124 @@
/************************************************************************
*
* W2LStarMathConverter.java
*
* Copyright: 2002-2008 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*/
// Version 1.0 (2008-11-22)
package org.openoffice.da.comp.writer2latex;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.lang.XTypeProvider;
import com.sun.star.uno.Type;
//import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.lang.XServiceName;
import writer2latex.api.ConverterFactory;
import writer2latex.api.StarMathConverter;
// Import interface as defined in uno idl
import org.openoffice.da.writer2latex.XW2LStarMathConverter;
/** This class provides a uno component which implements the interface
* org.openoffice.da.writer2latex.XW2LConverter
*/
public class W2LStarMathConverter implements
XW2LStarMathConverter,
XServiceName,
XServiceInfo,
XTypeProvider {
/** The component will be registered under this name.
*/
public static final String __serviceName = "org.openoffice.da.writer2latex.W2LStarMathConverter";
public static final String __implementationName = "org.openoffice.da.comp.writer2latex.W2LStarMathConverter";
//private static XComponentContext xComponentContext = null;
private static StarMathConverter starMathConverter;
public W2LStarMathConverter(XComponentContext xComponentContext1) {
starMathConverter = ConverterFactory.createStarMathConverter();
}
// Implementation of XW2LConverter:
public String convertFormula(String sStarMathFormula) {
return starMathConverter.convert(sStarMathFormula);
}
public String getPreamble() {
return starMathConverter.getPreamble();
}
// Implement methods from interface XTypeProvider
// Implementation of XTypeProvider
public com.sun.star.uno.Type[] getTypes() {
Type[] typeReturn = {};
try {
typeReturn = new Type[] {
new Type( XW2LStarMathConverter.class ),
new Type( XTypeProvider.class ),
new Type( XServiceName.class ),
new Type( XServiceInfo.class ) };
}
catch( Exception exception ) {
}
return( typeReturn );
}
public byte[] getImplementationId() {
byte[] byteReturn = {};
byteReturn = new String( "" + this.hashCode() ).getBytes();
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 ) );
}
public String getImplementationName() {
return( __implementationName );
}
public String[] getSupportedServiceNames() {
String[] stringSupportedServiceNames = { __serviceName };
return( stringSupportedServiceNames );
}
}

View file

@ -0,0 +1,230 @@
/************************************************************************
*
* Writer2LaTeX.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-05-29)
*
*/
package org.openoffice.da.comp.writer2latex;
import com.sun.star.beans.XPropertySet;
import com.sun.star.frame.XFrame;
import com.sun.star.lib.uno.helper.WeakBase;
import com.sun.star.ui.dialogs.ExecutableDialogResults;
import com.sun.star.ui.dialogs.XExecutableDialog;
import com.sun.star.uno.Exception;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import org.openoffice.da.comp.w2lcommon.filter.UNOPublisher.TargetFormat;
import org.openoffice.da.comp.w2lcommon.helper.MessageBox;
import org.openoffice.da.comp.w2lcommon.helper.RegistryHelper;
import org.openoffice.da.comp.w2lcommon.helper.XPropertySetHelper;
/** This class implements the ui (dispatch) commands provided by the Writer2LaTeX toolbar.
* The actual processing is done by the core classes <code>UNOPublisher</code>,
* <code>LaTeXImporter</code> and the dialogs
*/
public final class Writer2LaTeX 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.writer2latex:"; //$NON-NLS-1$
// From constructor+initialization
private final XComponentContext m_xContext;
private XFrame m_xFrame;
private LaTeXUNOPublisher unoPublisher = null;
public static final String __implementationName = Writer2LaTeX.class.getName();
public static final String __serviceName = "com.sun.star.frame.ProtocolHandler"; //$NON-NLS-1$
private static final String[] m_serviceNames = { __serviceName };
public Writer2LaTeX( 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]);
}
}
// 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("ProcessDocument") == 0 ) //$NON-NLS-1$
return this;
else if ( aURL.Path.compareTo("ViewLog") == 0 ) //$NON-NLS-1$
return this;
else if ( aURL.Path.compareTo("InsertBibTeX") == 0 ) //$NON-NLS-1$
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 ) {
if ( aURL.Path.compareTo("ProcessDocument") == 0 ) { //$NON-NLS-1$
process();
return;
}
else if ( aURL.Path.compareTo("ViewLog") == 0 ) { //$NON-NLS-1$
viewLog();
return;
}
else if ( aURL.Path.compareTo("InsertBibTeX") == 0 ) { //$NON-NLS-1$
insertBibTeX();
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 process() {
createUNOPublisher();
unoPublisher.publish(TargetFormat.latex);
}
private void viewLog() {
createUNOPublisher();
if (unoPublisher.documentSaved()) {
// Execute the log viewer dialog
try {
Object[] args = new Object[1];
args[0] = unoPublisher.getTargetPath()+unoPublisher.getTargetFileName();
Object dialog = m_xContext.getServiceManager()
.createInstanceWithArgumentsAndContext(
"org.openoffice.da.writer2latex.LogViewerDialog", args, m_xContext); //$NON-NLS-1$
XExecutableDialog xDialog = (XExecutableDialog)
UnoRuntime.queryInterface(XExecutableDialog.class, dialog);
if (xDialog.execute()==ExecutableDialogResults.OK) {
// Closed with the close button
}
}
catch (com.sun.star.uno.Exception e) {
}
}
}
private void insertBibTeX() {
if (useExternalBibTeXFiles()) {
createUNOPublisher();
if (unoPublisher.documentSaved()) {
// Execute the BibTeX dialog
try {
// The dialog needs the current frame and the path to the BibTeX directory
Object[] args = new Object[2];
args[0] = m_xFrame;
args[1] = unoPublisher.getBibTeXDirectory().getPath();
Object dialog = m_xContext.getServiceManager()
.createInstanceWithArgumentsAndContext(
"org.openoffice.da.writer2latex.BibTeXDialog", args, m_xContext); //$NON-NLS-1$
XExecutableDialog xDialog = (XExecutableDialog)
UnoRuntime.queryInterface(XExecutableDialog.class, dialog);
if (xDialog.execute()==ExecutableDialogResults.OK) {
// Closed with the close button
}
}
catch (com.sun.star.uno.Exception e) {
}
}
}
else {
MessageBox msgBox = new MessageBox(m_xContext, m_xFrame);
msgBox.showMessage("Writer2LaTeX",Messages.getString("Writer2LaTeX.bibtexnotenabled")); //$NON-NLS-1$
}
}
private boolean useExternalBibTeXFiles() {
// Get the BibTeX settings from the registry
RegistryHelper registry = new RegistryHelper(m_xContext);
Object view;
try {
view = registry.getRegistryView(BibliographyDialog.REGISTRY_PATH, false);
} catch (Exception e) {
// Failed to get registry settings
return false;
}
XPropertySet xProps = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class,view);
return XPropertySetHelper.getPropertyValueAsBoolean(xProps, "UseExternalBibTeXFiles"); //$NON-NLS-1$
}
private void createUNOPublisher() {
if (unoPublisher==null) {
unoPublisher = new LaTeXUNOPublisher(m_xContext,m_xFrame,"Writer2LaTeX"); //$NON-NLS-1$
}
}
}

View file

@ -0,0 +1,34 @@
ApplicationsDialog.configresults=Results of configuration
ApplicationsDialog.failedtofind=Failed to find
ApplicationsDialog.failedtofindmiktex=Failed to find MikTeX
ApplicationsDialog.found=Found
ApplicationsDialog.foundgsview=Found gsview
ApplicationsDialog.foundmiktex=Found MikTeX
ApplicationsDialog.miktexdefaultconfig=Writer2LaTeX has been configured to work if MikTeX is added to your path
ApplicationsDialog.ok=OK
ApplicationsDialog.pdfdefaultviewer=Using default application for PDF
ApplicationsDialog.psdefaultviewer=Using default application for PostScript
ApplicationsDialog.systemident=Your system identifies itself as
ApplicationsDialog.usingdefaultapp=Using default application as
ApplicationsDialog.version=version
BibliographyDialog.nobibtexfiles=Warning: The selected directory does not contain any BibTeX files
BibTeXDialog.allbibfieldsupdated=All bibliography fields were updated
BibTeXDialog.alreadyexists=already exists
BibTeXDialog.bibfieldsnotupdated=The following bibliography fields were not updated
BibTeXDialog.errorreadingfile=There was an error reading this file
BibTeXDialog.failedbibtexeditor=Error: Failed to open file with BibTeX editor
BibTeXDialog.filenameempty=The file name is empty
BibTeXDialog.nobibtexeditor=Error: No BibTeX editor was found
BibTeXDialog.nobibtexfiles=No BibTeX files were found
BibTeXDialog.noentries=This file does not contain any entries
BibTeXDialog.noinformation=No information
BibTeXDialog.thefile=The file
ExternalApps.dviviewer=DVI Viewer
ExternalApps.pdfviewer=PDF Viewer
ExternalApps.psviewer=PostScript Viewer
LaTeXUNOPublisher.error=Error
LaTeXUNOPublisher.failedlatex=Failed to execute LaTeX - see log for details
TeXify.dviviewerror=Error executing DVI viewer
TeXify.pdfviewerror=Error executing PDF viewer
TeXify.psviewerror=Error executing PostScript viewer
Writer2LaTeX.bibtexnotenabled=Writer2LaTeX is not configured to use external BibTeX files for citations

View file

@ -0,0 +1,34 @@
ApplicationsDialog.configresults=Resultat af konfigurationen
ApplicationsDialog.failedtofind=Fandt ikke
ApplicationsDialog.failedtofindmiktex=Fandt ikke MikTeX
ApplicationsDialog.found=Fandt
ApplicationsDialog.foundgsview=Fandt gsview
ApplicationsDialog.foundmiktex=Fandt MikTeX
ApplicationsDialog.miktexdefaultconfig=Writer2LaTeX er blevet konfigureret så det virker hvis MikTeX tilføjes til din PATH
ApplicationsDialog.ok=o.k.
ApplicationsDialog.pdfdefaultviewer=Bruger standardprogram til PDF
ApplicationsDialog.psdefaultviewer=Bruger standardprogram til PostScript
ApplicationsDialog.systemident=Dit system identificerer sig som
ApplicationsDialog.usingdefaultapp=Bruger standardprogram som
ApplicationsDialog.version=version
BibliographyDialog.nobibtexfiles=Advarsel: Den valgte mappe indeholder ingen BibTeX filer
BibTeXDialog.allbibfieldsupdated=Alle litteraturlisteelementer blev opdateret
BibTeXDialog.alreadyexists=findes allerede
BibTeXDialog.bibfieldsnotupdated=Følgende litteraturlisteelementer blev ikke opdateret
BibTeXDialog.errorreadingfile=Der skete en fejl ved læsning af denne fil
BibTeXDialog.failedbibtexeditor=Fejl: Kunne ikke åbne filen med BibTeX-redigeringsprogrammet
BibTeXDialog.filenameempty=Filnavnet er tomt
BibTeXDialog.nobibtexeditor=Fejl: Kunne ikke finde et BibTeX-redigeringsprogram
BibTeXDialog.nobibtexfiles=Fandt ingen BibTeX filer
BibTeXDialog.noentries=Filen indeholder ingen elementer
BibTeXDialog.noinformation=Ingen information
BibTeXDialog.thefile=Filen
ExternalApps.dviviewer=DVI-fremviser
ExternalApps.pdfviewer=PDF-fremviser
ExternalApps.psviewer=PostScript-fremviser
LaTeXUNOPublisher.error=Fejl
LaTeXUNOPublisher.failedlatex=Kunne ikke køre LaTeX - se loggen for detaljer
TeXify.dviviewerror=Fejl ved åbning af DVI-fremviser
TeXify.pdfviewerror=Fejl ved åbning af PDF-fremviser
TeXify.psviewerror=Fejl ved åbning af PostScript-fremviser
Writer2LaTeX.bibtexnotenabled=Writer2LaTeX er ikke sat op til at bruge eksterne BibTeX-filer til litteraturhenvisninger

View file

@ -0,0 +1,520 @@
/************************************************************************
*
* BatchConverter.java
*
* Copyright: 2002-2009 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.3.1 (2014-08-04)
*
*/
package org.openoffice.da.comp.writer2xhtml;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import com.sun.star.lib.uno.adapter.XInputStreamToInputStreamAdapter;
import com.sun.star.lib.uno.adapter.XOutputStreamToOutputStreamAdapter;
import com.sun.star.beans.PropertyValue;
import com.sun.star.document.XDocumentProperties;
import com.sun.star.document.XDocumentPropertiesSupplier;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.frame.XStorable;
import com.sun.star.io.NotConnectedException;
import com.sun.star.io.XInputStream;
import com.sun.star.io.XOutputStream;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.lang.XServiceName;
import com.sun.star.lang.XTypeProvider;
import com.sun.star.sheet.XSpreadsheetDocument;
import com.sun.star.text.XTextDocument;
import com.sun.star.ucb.CommandAbortedException;
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;
//import writer2latex.api.BatchConverter;
//import writer2latex.api.BatchHandler;
//import writer2latex.api.Converter;
import writer2latex.api.ConverterFactory;
import writer2latex.api.IndexPageEntry;
import writer2latex.api.MIMETypes;
import writer2latex.api.OutputFile;
// Import interfaces as defined in uno idl
import org.openoffice.da.writer2xhtml.XBatchConverter;
import org.openoffice.da.writer2xhtml.XBatchHandler;
import org.openoffice.da.comp.w2lcommon.helper.PropertyHelper;
/** This class provides a uno component which implements the interface
* org.openoffice.da.writer2xhtml.XBatchConverter
*/
public class BatchConverter implements
XBatchConverter,
XServiceName,
XServiceInfo,
XTypeProvider {
/** The component will be registered under this name.
*/
public static final String __serviceName = "org.openoffice.da.writer2xhtml.BatchConverter";
public static final String __implementationName = "org.openoffice.da.comp.writer2xhtml.BatchConverter";
private XComponentContext xComponentContext = null;
private XSimpleFileAccess2 sfa2 = null;
private writer2latex.api.BatchConverter batchConverter = null;
private XBatchHandler handler;
// Based on convert arguments
private boolean bRecurse = true;
private String sWriterFilterName = "org.openoffice.da.writer2xhtml";
private Object writerFilterData = null;
private String sCalcFilterName = "org.openoffice.da.calc2xhtml";
private Object calcFilterData = null;
private boolean bIncludePdf = true;
private boolean bIncludeOriginal = false;
private boolean bUseTitle = true;
private boolean bUseDescription = true;
private String sUplink = "";
private String sDirectoryIcon = "";
private String sDocumentIcon = "";
private String sTemplateURL = null;
public BatchConverter(XComponentContext xComponentContext) {
this.xComponentContext = xComponentContext;
// Get the SimpleFileAccess service
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)
}
}
// Helper: Get a string from an any
private String getValue(Object any) {
if (AnyConverter.isString(any)) {
try {
return AnyConverter.toString(any);
}
catch (com.sun.star.lang.IllegalArgumentException e) {
return "";
}
}
else {
return "";
}
}
// Implementation of XBatchConverter:
public void convert(String sSourceURL, String sTargetURL, PropertyValue[] lArguments, XBatchHandler handler) {
// Create batch converter (currently we don't need to set a converter)
batchConverter = ConverterFactory.createBatchConverter(MIMETypes.XHTML);
this.handler = handler;
// Read the arguments
int nSize = lArguments.length;
for (int i=0; i<nSize; i++) {
String sName = lArguments[i].Name;
Object value = lArguments[i].Value;
if ("Recurse".equals(sName)) {
bRecurse = !"false".equals(getValue(value));
}
else if ("IncludePdf".equals(sName)) {
bIncludePdf = !"false".equals(getValue(value));
}
else if ("IncludeOriginal".equals(sName)) {
bIncludeOriginal = "true".equals(getValue(value));
}
else if ("UseTitle".equals(sName)) {
bUseTitle = !"false".equals(getValue(value));
}
else if ("UseDescription".equals(sName)) {
bUseDescription = !"false".equals(getValue(value));
}
else if ("Uplink".equals(sName)) {
sUplink = getValue(value);
}
else if ("DirectoryIcon".equals(sName)) {
sDirectoryIcon = getValue(value);
}
else if ("DocumentIcon".equals(sName)) {
sDocumentIcon = getValue(value);
}
else if ("TemplateURL".equals(sName)) {
sTemplateURL = getValue(value);
}
else if ("WriterFilterName".equals(sName)) {
sWriterFilterName = getValue(value);
}
else if ("WriterFilterData".equals(sName)) {
writerFilterData = lArguments[i].Value;
}
else if ("CalcFilterName".equals(sName)) {
sCalcFilterName = getValue(value);
}
else if ("CalcFilterData".equals(sName)) {
calcFilterData = lArguments[i].Value;
}
}
// Set arguments on batch converter
batchConverter.getConfig().setOption("uplink", sUplink);
batchConverter.getConfig().setOption("directory_icon", sDirectoryIcon);
batchConverter.getConfig().setOption("document_icon", sDocumentIcon);
if (sTemplateURL!=null) {
try {
XInputStream xis = sfa2.openFileRead(sTemplateURL);
XInputStreamToInputStreamAdapter isa = new XInputStreamToInputStreamAdapter(xis);
batchConverter.readTemplate(isa);
}
catch (IOException e) {
// The batchconverter failed to read the template
}
catch (CommandAbortedException e) {
// The sfa could not execute the command
}
catch (com.sun.star.uno.Exception e) {
// Unspecified uno exception
}
}
// Convert the directory
handler.startConversion();
convertDirectory(sSourceURL, sTargetURL, getName(sSourceURL));
handler.endConversion();
}
// Convert a directory - return true if not cancelled
private boolean convertDirectory(String sSourceURL, String sTargetURL, String sHeading) {
handler.startDirectory(sSourceURL);
// Step 1: Get the directory
String[] contents;
try {
contents = sfa2.getFolderContents(sSourceURL, true);
}
catch (CommandAbortedException e) {
handler.endDirectory(sSourceURL,false);
return true;
}
catch (com.sun.star.uno.Exception e) {
handler.endDirectory(sSourceURL,false);
return true;
}
int nLen = contents.length;
IndexPageEntry[] entries = new IndexPageEntry[nLen];
// Step 2: Traverse subdirectories, if allowed
if (bRecurse) {
String sUplink = batchConverter.getConfig().getOption("uplink");
for (int i=0; i<nLen; i++) {
boolean bIsDirectory = false;
try {
bIsDirectory = sfa2.isFolder(contents[i]);
}
catch (CommandAbortedException e) {
// Considered non critical, ignore
}
catch (com.sun.star.uno.Exception e) {
// Considered non critical, ignore
}
if (bIsDirectory) {
batchConverter.getConfig().setOption("uplink","../index.html");
String sNewTargetURL = ensureSlash(sTargetURL) + getName(contents[i]);
String sNewHeading = sHeading + " - " + decodeURL(getName(contents[i]));
boolean bResult = convertDirectory(contents[i],sNewTargetURL,sNewHeading);
batchConverter.getConfig().setOption("uplink", sUplink);
if (!bResult) { return false; }
// Create entry for this subdirectory
IndexPageEntry entry = new IndexPageEntry(ensureSlash(sNewTargetURL)+"index.html",true);
entry.setDisplayName(decodeURL(getName(contents[i])));
entries[i]=entry;
}
}
}
// Step 3: Traverse documents
for (int i=0; i<nLen; i++) {
boolean bIsFile = false;
try {
bIsFile = sfa2.exists(contents[i]) && !sfa2.isFolder(contents[i]);
}
catch (CommandAbortedException e) {
// Considered non critical, ignore
}
catch (com.sun.star.uno.Exception e) {
// Considered non critical, ignore
}
if (bIsFile) {
IndexPageEntry entry = convertFile(contents[i],sTargetURL);
if (entry!=null) { entries[i]=entry; }
if (handler.cancel()) { return false; }
}
}
// Step 4: Create and write out the index file
OutputFile indexFile = batchConverter.createIndexFile(sHeading, entries);
try {
if (!sfa2.exists(sTargetURL)) { sfa2.createFolder(sTargetURL); }
}
catch (CommandAbortedException e) {
handler.endDirectory(sSourceURL,false);
return true;
}
catch (com.sun.star.uno.Exception e) {
handler.endDirectory(sSourceURL,false);
return true;
}
try {
// writeFile demands an InputStream, so we need a pipe
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...
indexFile.write(outStream);
outStream.flush();
outStream.close();
xOutStream.closeOutput();
// ...and then write the content to the url
sfa2.writeFile(ensureSlash(sTargetURL)+"index.html",xInStream);
}
catch (IOException e) {
handler.endDirectory(sSourceURL,false);
return true;
}
catch (NotConnectedException e) {
handler.endDirectory(sSourceURL,false);
return true;
}
catch (com.sun.star.uno.Exception e) {
handler.endDirectory(sSourceURL,false);
return true;
}
handler.endDirectory(sSourceURL, true);
return !handler.cancel();
}
private IndexPageEntry convertFile(String sSourceFileURL, String sTargetURL) {
handler.startFile(sSourceFileURL);
String sTargetFileURL = ensureSlash(sTargetURL) + getBaseName(sSourceFileURL) + ".html";
IndexPageEntry entry = new IndexPageEntry(getName(sTargetFileURL),false);
entry.setDisplayName(decodeURL(getBaseName(sTargetFileURL)));
// Load component
XComponent xDocument;
try {
Object desktop = xComponentContext.getServiceManager().createInstanceWithContext(
"com.sun.star.frame.Desktop", xComponentContext);
XComponentLoader xComponentLoader = (XComponentLoader)
UnoRuntime.queryInterface(XComponentLoader.class, desktop);
PropertyValue[] fileProps = new PropertyValue[1];
fileProps[0] = new PropertyValue();
fileProps[0].Name = "Hidden";
fileProps[0].Value = new Boolean(true);
xDocument = xComponentLoader.loadComponentFromURL(sSourceFileURL, "_blank", 0, fileProps);
}
catch (com.sun.star.io.IOException e) {
handler.endFile(sSourceFileURL,false);
return null;
}
catch (com.sun.star.uno.Exception e) {
handler.endFile(sSourceFileURL,false);
return null;
}
// Get the title and the description of the document
XDocumentProperties docProps = UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, xDocument).getDocumentProperties();
String loadedTitle = docProps.getTitle();
if (bUseTitle && loadedTitle.length()>0) {
entry.setDisplayName(loadedTitle);
}
String loadedDescription = docProps.getDescription();
if (bUseDescription && loadedDescription.length()>0) {
entry.setDescription(loadedDescription);
}
// Determine the type of the component
boolean bText = false;
boolean bSpreadsheet = false;
if (UnoRuntime.queryInterface(XTextDocument.class, xDocument)!=null) { bText=true; }
else if (UnoRuntime.queryInterface(XSpreadsheetDocument.class, xDocument)!=null) { bSpreadsheet=true; }
if (!bText && !bSpreadsheet) {
handler.endFile(sSourceFileURL,false);
xDocument.dispose();
return null;
}
// Convert using requested filter
boolean bHtmlSuccess = true;
PropertyHelper exportProps = new PropertyHelper();
exportProps.put("FilterName", bText ? sWriterFilterName : sCalcFilterName);
exportProps.put("Overwrite", new Boolean(true));
if (bText && writerFilterData!=null) { exportProps.put("FilterData", writerFilterData); }
if (bSpreadsheet && calcFilterData!=null) { exportProps.put("FilterData", calcFilterData); }
try {
XStorable xStore = (XStorable) UnoRuntime.queryInterface (XStorable.class, xDocument);
xStore.storeToURL (sTargetFileURL, exportProps.toArray());
}
catch (com.sun.star.io.IOException e) {
// Failed to convert; continue anyway, but don't link to the file name
entry.setFile(null);
bHtmlSuccess = false;
}
// Convet to pdf if requested
boolean bPdfSuccess = true;
if (bIncludePdf) {
PropertyValue[] pdfProps = new PropertyValue[2];
pdfProps[0] = new PropertyValue();
pdfProps[0].Name = "FilterName";
pdfProps[0].Value = bText ? "writer_pdf_Export" : "calc_pdf_Export";
pdfProps[1] = new PropertyValue();
pdfProps[1].Name = "Overwrite";
pdfProps[1].Value = new Boolean(true);
String sPdfFileURL = ensureSlash(sTargetURL) + getBaseName(sSourceFileURL) + ".pdf";
try {
XStorable xStore = (XStorable) UnoRuntime.queryInterface (XStorable.class, xDocument);
xStore.storeToURL (sPdfFileURL, pdfProps);
entry.setPdfFile(sPdfFileURL);
}
catch (com.sun.star.io.IOException e) {
// Not critical, continue without pdf
bPdfSuccess = false;
}
}
xDocument.dispose();
// Include original document if required
if (bIncludeOriginal) {
// TODO
}
// Report a failure to the user if either of the exports failed
handler.endFile(sSourceFileURL,bHtmlSuccess && bPdfSuccess);
// But return the index entry even if only one succeded
if (bHtmlSuccess || bPdfSuccess) { return entry; }
else { return null; }
}
private String getName(String sURL) {
int n = sURL.lastIndexOf("/");
return n>-1 ? sURL.substring(n+1) : sURL;
}
private String getBaseName(String sURL) {
String sName = getName(sURL);
int n = sName.lastIndexOf(".");
return n>-1 ? sName.substring(0,n) : sName;
}
private String ensureSlash(String sURL) {
return sURL.endsWith("/") ? sURL : sURL+"/";
}
private String decodeURL(String sURL) {
try {
return new URI(sURL).getPath();
}
catch (URISyntaxException e) {
return sURL;
}
}
// Implement methods from interface XTypeProvider
public com.sun.star.uno.Type[] getTypes() {
Type[] typeReturn = {};
try {
typeReturn = new Type[] {
new Type( XBatchConverter.class ),
new Type( XTypeProvider.class ),
new Type( XServiceName.class ),
new Type( XServiceInfo.class ) };
}
catch( Exception exception ) {
}
return( typeReturn );
}
public byte[] getImplementationId() {
byte[] byteReturn = {};
byteReturn = new String( "" + this.hashCode() ).getBytes();
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 ) );
}
public String getImplementationName() {
return( __implementationName );
}
public String[] getSupportedServiceNames() {
String[] stringSupportedServiceNames = { __serviceName };
return( stringSupportedServiceNames );
}
}

View file

@ -0,0 +1,71 @@
/************************************************************************
*
* BatchHandlerAdapter.java
*
* Copyright: 2002-2008 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.0 (2008-10-05)
*
*/
package org.openoffice.da.comp.writer2xhtml;
import writer2latex.api.BatchHandler;
import org.openoffice.da.writer2xhtml.XBatchHandler;
/** The uno interface provides an XBatchHandler implementation, the java
* interface requires a BatchHandler implementation. This simple class
* implements the latter using an instance of the former.
*/
public class BatchHandlerAdapter implements BatchHandler {
private XBatchHandler unoHandler;
public BatchHandlerAdapter(XBatchHandler unoHandler) {
this.unoHandler = unoHandler;
}
public void startConversion() {
unoHandler.startConversion();
}
public void endConversion() {
unoHandler.endConversion();
}
public void startDirectory(String sName) {
unoHandler.startDirectory(sName);
}
public void endDirectory(String sName, boolean bSuccess) {
unoHandler.endDirectory(sName, bSuccess);
}
public void startFile(String sName) {
unoHandler.startFile(sName);
}
public void endFile(String sName, boolean bSuccess) {
unoHandler.endFile(sName, bSuccess);
}
public boolean cancel() {
return unoHandler.cancel();
}
}

View file

@ -0,0 +1,587 @@
/************************************************************************
*
* ConfigurationDialog.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-06-16)
*
*/
package org.openoffice.da.comp.writer2xhtml;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Map;
import org.openoffice.da.comp.w2lcommon.filter.ConfigurationDialogBase;
import org.openoffice.da.comp.w2lcommon.helper.DialogAccess;
import writer2latex.api.Converter;
import writer2latex.api.ConverterFactory;
import com.sun.star.container.NoSuchElementException;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.ucb.CommandAbortedException;
import com.sun.star.uno.Exception;
import com.sun.star.uno.XComponentContext;
public class ConfigurationDialog extends ConfigurationDialogBase implements XServiceInfo {
private String sResourceDirName;
// Implement the interface XServiceInfo
/** The component will be registered under this name.
*/
public static String __serviceName = "org.openoffice.da.writer2xhtml.ConfigurationDialog";
/** The component should also have an implementation name.
*/
public static String __implementationName = "org.openoffice.da.comp.writer2xhtml.ConfigurationDialog";
public boolean supportsService(String sServiceName) {
return sServiceName.equals(__serviceName);
}
public String getImplementationName() {
return __implementationName;
}
public String[] getSupportedServiceNames() {
String[] sSupportedServiceNames = { __serviceName };
return sSupportedServiceNames;
}
// Configure the base class
@Override protected String getMIMEType() { return "text/html"; }
@Override protected String getDialogLibraryName() { return "W2XDialogs2"; }
@Override protected String getConfigFileName() { return "writer2xhtml.xml"; }
/** Construct a new <code>ConfigurationDialog</code> */
public ConfigurationDialog(XComponentContext xContext) {
super(xContext);
// Create the resource dir name
try {
sResourceDirName = xPathSub.substituteVariables("$(user)/writer2xhtml-resources", false);
}
catch (NoSuchElementException e) {
sResourceDirName = "writer2xhtml-resources";
}
pageHandlers.put("General", new GeneralHandler());
pageHandlers.put("Template", new TemplateHandler());
pageHandlers.put("Stylesheets", new StylesheetsHandler());
pageHandlers.put("Formatting", new FormattingHandler());
pageHandlers.put("Styles1", new Styles1Handler());
pageHandlers.put("Styles2", new Styles2Handler());
pageHandlers.put("Formatting", new FormattingHandler());
pageHandlers.put("Content", new ContentHandler());
}
// Implement remaining method from XContainerWindowEventHandler
public String[] getSupportedMethodNames() {
String[] sNames = { "EncodingChange", // General
"CustomTemplateChange", "LoadTemplateClick", "TemplateKeyup", // Template
"UseCustomStylesheetChange", "IncludeCustomStylesheetClick", "LoadStylesheetClick",
"NewResourceClick", "DeleteResourceClick", // Stylesheet
"StyleFamilyChange", "StyleNameChange", "NewStyleClick", "DeleteStyleClick", "LoadDefaultsClick" // Styles1
};
return sNames;
}
// the page handlers
private final String[] sCharElements = { "span", "abbr", "acronym", "b", "big", "cite", "code", "del", "dfn", "em", "i",
"ins", "kbd", "samp", "small", "strong", "sub", "sup", "tt", "var", "q" };
private class GeneralHandler extends PageHandler {
private final String[] sEncodingValues = { "UTF-8", "UTF-16", "ISO-8859-1", "US-ASCII" };
@Override protected void setControls(DialogAccess dlg) {
checkBoxFromConfig(dlg, "NoDoctype", "no_doctype");
listBoxFromConfig(dlg, "Encoding", "encoding", sEncodingValues, (short) 0);
checkBoxFromConfig(dlg, "AddBOM", "add_bom");
if ("true".equals(config.getOption("hexadecimal_entities"))) {
dlg.setListBoxSelectedItem("HexadecimalEntities", (short) 0);
}
else {
dlg.setListBoxSelectedItem("HexadecimalEntities", (short) 1);
}
checkBoxFromConfig(dlg, "UseNamedEntities", "use_named_entities");
checkBoxFromConfig(dlg, "Multilingual", "multilingual");
checkBoxFromConfig(dlg, "PrettyPrint", "pretty_print");
encodingChange(dlg);
}
@Override protected void getControls(DialogAccess dlg) {
checkBoxToConfig(dlg, "NoDoctype", "no_doctype");
listBoxToConfig(dlg, "Encoding", "encoding", sEncodingValues);
checkBoxToConfig(dlg, "AddBOM", "add_bom");
config.setOption("hexadecimal_entities", Boolean.toString(dlg.getListBoxSelectedItem("HexadecimalEntities")==(short)0));
checkBoxToConfig(dlg, "UseNamedEntities", "use_named_entities");
checkBoxToConfig(dlg, "Multilingual", "multilingual");
checkBoxToConfig(dlg, "PrettyPrint", "pretty_print");
}
@Override protected boolean handleEvent(DialogAccess dlg, String sMethod) {
if (sMethod.equals("EncodingChange")) {
encodingChange(dlg);
return true;
}
return false;
}
private void encodingChange(DialogAccess dlg) {
int nEncoding = dlg.getListBoxSelectedItem("Encoding");
dlg.setControlEnabled("AddBOM", nEncoding==0); // Only for UTF-8
dlg.setControlEnabled("HexadecimalEntitiesLabel", nEncoding>1); // Not for UNICODE
dlg.setControlEnabled("HexadecimalEntities", nEncoding>1); // Not for UNICODE
}
}
private class TemplateHandler extends CustomFileHandler {
protected String getSuffix() {
return "Template";
}
protected String getFileName() {
return "writer2xhtml-template.xhtml";
}
protected void useCustomInner(DialogAccess dlg, boolean bEnable) {
dlg.setControlEnabled("TestTemplateLabel", bEnable);
dlg.setControlEnabled("ContentIdLabel", bEnable);
dlg.setControlEnabled("ContentId", bEnable);
dlg.setControlEnabled("HeaderIdLabel", bEnable);
dlg.setControlEnabled("HeaderId", bEnable);
dlg.setControlEnabled("FooterIdLabel", bEnable);
dlg.setControlEnabled("FooterId", bEnable);
dlg.setControlEnabled("PanelIdLabel", bEnable);
dlg.setControlEnabled("PanelId", bEnable);
}
@Override protected void setControls(DialogAccess dlg) {
super.setControls(dlg);
String[] sCustomIds = config.getOption("template_ids").split(",");
if (sCustomIds.length>0) { dlg.setComboBoxText("ContentId", sCustomIds[0]); }
if (sCustomIds.length>1) { dlg.setComboBoxText("HeaderId", sCustomIds[1]); }
if (sCustomIds.length>2) { dlg.setComboBoxText("FooterId", sCustomIds[2]); }
if (sCustomIds.length>3) { dlg.setComboBoxText("PanelId", sCustomIds[3]); }
testTemplate(dlg);
}
@Override protected void getControls(DialogAccess dlg) {
super.getControls(dlg);
config.setOption("template_ids",
dlg.getComboBoxText("ContentId").trim()+","+
dlg.getComboBoxText("HeaderId").trim()+","+
dlg.getComboBoxText("FooterId").trim()+","+
dlg.getComboBoxText("PanelId").trim());
}
@Override protected boolean handleEvent(DialogAccess dlg, String sMethod) {
if (super.handleEvent(dlg, sMethod)) {
return true;
}
if (sMethod.equals("TemplateKeyup")) {
testTemplate(dlg);
return true;
}
return false;
}
@Override protected void loadCustomClick(DialogAccess dlg) {
super.loadCustomClick(dlg);
testTemplate(dlg);
}
private void testTemplate(DialogAccess dlg) {
Converter converter = ConverterFactory.createConverter("text/html");
String sTemplate = dlg.getTextFieldText("CustomTemplate").trim();
if (sTemplate.length()>0) { // Only display error message if there is content
try {
converter.readTemplate(new ByteArrayInputStream(sTemplate.getBytes()));
dlg.setLabelText("TestTemplateLabel", "");
} catch (IOException e) {
dlg.setLabelText("TestTemplateLabel", "ERROR: "+e.getMessage());
}
}
else {
dlg.setLabelText("TestTemplateLabel", "");
}
}
}
private class StylesheetsHandler extends CustomFileHandler {
protected String getSuffix() {
return "Stylesheet";
}
protected String getFileName() {
return "writer2xhtml-styles.css";
}
protected void useCustomInner(DialogAccess dlg, boolean bEnable) {
dlg.setControlEnabled("ResourceLabel", bEnable);
dlg.setControlEnabled("Resources", bEnable);
dlg.setControlEnabled("NewResourceButton", bEnable);
dlg.setControlEnabled("DeleteResourceButton", bEnable);
updateResources(dlg);
}
@Override protected void setControls(DialogAccess dlg) {
super.setControls(dlg);
dlg.setCheckBoxStateAsBoolean("LinkCustomStylesheet", config.getOption("custom_stylesheet").length()>0);
textFieldFromConfig(dlg, "CustomStylesheetURL", "custom_stylesheet");
linkCustomStylesheetChange(dlg);
updateResources(dlg);
}
@Override protected void getControls(DialogAccess dlg) {
super.getControls(dlg);
if (dlg.getCheckBoxStateAsBoolean("LinkCustomStylesheet")) {
textFieldToConfig(dlg, "CustomStylesheetURL", "custom_stylesheet");
}
else {
config.setOption("custom_stylesheet", "");
}
}
@Override protected boolean handleEvent(DialogAccess dlg, String sMethod) {
if (super.handleEvent(dlg, sMethod)) {
return true;
}
if (sMethod.equals("LinkCustomStylesheetChange")) {
linkCustomStylesheetChange(dlg);
return true;
}
else if (sMethod.equals("NewResourceClick")) {
newResourceClick(dlg);
return true;
}
else if (sMethod.equals("DeleteResourceClick")) {
deleteResourceClick(dlg);
return true;
}
return false;
}
private void linkCustomStylesheetChange(DialogAccess dlg) {
boolean bLinkCustomStylesheet = dlg.getCheckBoxStateAsBoolean("LinkCustomStylesheet");
dlg.setControlEnabled("CustomStylesheetURLLabel", bLinkCustomStylesheet);
dlg.setControlEnabled("CustomStylesheetURL", bLinkCustomStylesheet);
}
private void newResourceClick(DialogAccess dlg) {
String[] sFileNames=filePicker.getPaths();
if (sFileNames!=null) {
createResourceDir();
for (String sFileName : sFileNames) {
String sBaseFileName = sFileName.substring(sFileName.lastIndexOf('/')+1);
try {
String sTargetFileName = sResourceDirName+"/"+sBaseFileName;
if (fileExists(sTargetFileName)) { killFile(sTargetFileName); }
sfa2.copy(sFileName, sTargetFileName);
} catch (CommandAbortedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
updateResources(dlg);
}
}
private void deleteResourceClick(DialogAccess dlg) {
int nItem = dlg.getListBoxSelectedItem("Resources");
if (nItem>=0) {
String sFileName = dlg.getListBoxStringItemList("Resources")[nItem];
if (deleteItem(sFileName)) {
killFile(sResourceDirName+"/"+sFileName);
updateResources(dlg);
}
}
}
private void updateResources(DialogAccess dlg) {
createResourceDir();
try {
String[] sFiles = sfa2.getFolderContents(sResourceDirName, false); // do not include folders
int nCount = sFiles.length;
for (int i=0; i<nCount; i++) {
sFiles[i] = sFiles[i].substring(sFiles[i].lastIndexOf('/')+1);
}
dlg.setListBoxStringItemList("Resources", sFiles);
} catch (CommandAbortedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
private void createResourceDir() {
try {
if (!sfa2.isFolder(sResourceDirName)) {
sfa2.createFolder(sResourceDirName);
}
} catch (CommandAbortedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private class Styles1Handler extends StylesPageHandler {
private final String[] sXhtmlFamilyNames = { "text", "paragraph", "heading", "list", "frame" };
private final String[] sXhtmlOOoFamilyNames = { "CharacterStyles", "ParagraphStyles", "ParagraphStyles", "NumberingStyles", "FrameStyles" };
private final String[] sParElements = { "p", "h1", "h2", "h3", "h4", "h5", "h6", "address", "dd", "dt", "pre" };
private final String[] sParBlockElements = { "div", "blockquote", "dl" };
private final String[] sEmpty = { };
private String[][] sElements = new String[5][];
private String[][] sBlockElements = new String[5][];
protected Styles1Handler() {
super(5);
sFamilyNames = sXhtmlFamilyNames;
sOOoFamilyNames = sXhtmlOOoFamilyNames;
sElements[0] = sCharElements;
sElements[1] = sParElements;
sElements[2] = sParElements;
sElements[3] = sEmpty;
sElements[4] = sEmpty;
sBlockElements[0] = sEmpty;
sBlockElements[1] = sParBlockElements;
sBlockElements[2] = sParBlockElements;
sBlockElements[3] = sEmpty;
sBlockElements[4] = sEmpty;
}
protected String getDefaultConfigName() {
return "cleanxhtml.xml";
}
protected void setControls(DialogAccess dlg, Map<String,String> attr) {
if (!attr.containsKey("element")) { attr.put("element", ""); }
if (!attr.containsKey("css")) { attr.put("css", ""); }
dlg.setComboBoxText("Element", attr.get("element"));
dlg.setTextFieldText("Css", none2empty(attr.get("css")));
if (nCurrentFamily==1 || nCurrentFamily==2) {
if (!attr.containsKey("before")) { attr.put("before", ""); }
if (!attr.containsKey("after")) { attr.put("after", ""); }
dlg.setTextFieldText("Before", attr.get("before"));
dlg.setTextFieldText("After", attr.get("after"));
}
else {
dlg.setTextFieldText("Before", "");
dlg.setTextFieldText("After", "");
}
if (nCurrentFamily==1 || nCurrentFamily==2) {
if (!attr.containsKey("block-element")) { attr.put("block-element", ""); }
if (!attr.containsKey("block-css")) { attr.put("block-css", ""); }
dlg.setComboBoxText("BlockElement", attr.get("block-element"));
dlg.setTextFieldText("BlockCss", none2empty(attr.get("block-css")));
}
else {
dlg.setComboBoxText("BlockElement", "");
dlg.setTextFieldText("BlockCss", "");
}
}
protected void getControls(DialogAccess dlg, Map<String,String> attr) {
attr.put("element", dlg.getComboBoxText("Element"));
attr.put("css", empty2none(dlg.getTextFieldText("Css")));
if (nCurrentFamily==1 || nCurrentFamily==2) {
attr.put("before", dlg.getTextFieldText("Before"));
attr.put("after", dlg.getTextFieldText("After"));
}
if (nCurrentFamily==1 || nCurrentFamily==2) {
attr.put("block-element", dlg.getComboBoxText("BlockElement"));
attr.put("block-css", empty2none(dlg.getTextFieldText("BlockCss")));
}
}
protected void clearControls(DialogAccess dlg) {
dlg.setComboBoxText("Element", "");
dlg.setTextFieldText("Css", "");
dlg.setTextFieldText("Before", "");
dlg.setTextFieldText("After", "");
dlg.setComboBoxText("BlockElement", "");
dlg.setTextFieldText("BlockCss", "");
}
protected void prepareControls(DialogAccess dlg, boolean bHasMappings) {
dlg.setListBoxStringItemList("Element", sElements[nCurrentFamily]);
dlg.setListBoxStringItemList("BlockElement", sBlockElements[nCurrentFamily]);
dlg.setControlEnabled("ElementLabel", bHasMappings && nCurrentFamily<=2);
dlg.setControlEnabled("Element", bHasMappings && nCurrentFamily<=2);
dlg.setControlEnabled("CssLabel", bHasMappings);
dlg.setControlEnabled("Css", bHasMappings);
dlg.setControlEnabled("BeforeLabel", bHasMappings && (nCurrentFamily==1 || nCurrentFamily==2));
dlg.setControlEnabled("Before", bHasMappings && (nCurrentFamily==1 || nCurrentFamily==2));
dlg.setControlEnabled("AfterLabel", bHasMappings && (nCurrentFamily==1 || nCurrentFamily==2));
dlg.setControlEnabled("After", bHasMappings && (nCurrentFamily==1 || nCurrentFamily==2));
dlg.setControlEnabled("BlockElementLabel", bHasMappings && (nCurrentFamily==1 || nCurrentFamily==2));
dlg.setControlEnabled("BlockElement", bHasMappings && (nCurrentFamily==1 || nCurrentFamily==2));
dlg.setControlEnabled("BlockCssLabel", bHasMappings && (nCurrentFamily==1 || nCurrentFamily==2));
dlg.setControlEnabled("BlockCss", bHasMappings && (nCurrentFamily==1 || nCurrentFamily==2));
}
}
private class Styles2Handler extends AttributePageHandler {
private String[] sXhtmlAttributeNames = { "bold", "italics", "fixed", "superscript", "subscript", "underline", "overstrike" };
public Styles2Handler() {
sAttributeNames = sXhtmlAttributeNames;
}
@Override public void setControls(DialogAccess dlg) {
super.setControls(dlg);
textFieldFromConfig(dlg,"TabstopStyle","tabstop_style");
}
@Override public void getControls(DialogAccess dlg) {
super.getControls(dlg);
textFieldToConfig(dlg,"TabstopStyle","tabstop_style");
}
protected void setControls(DialogAccess dlg, Map<String,String> attr) {
if (!attr.containsKey("element")) { attr.put("element", ""); }
if (!attr.containsKey("css")) { attr.put("css", ""); }
dlg.setListBoxStringItemList("Element", sCharElements);
dlg.setComboBoxText("Element", attr.get("element"));
dlg.setTextFieldText("Css", none2empty(attr.get("css")));
}
protected void getControls(DialogAccess dlg, Map<String,String> attr) {
attr.put("element", dlg.getComboBoxText("Element"));
attr.put("css", empty2none(dlg.getTextFieldText("Css")));
}
protected void prepareControls(DialogAccess dlg, boolean bEnable) {
dlg.setControlEnabled("ElementLabel", bEnable);
dlg.setControlEnabled("Element", bEnable);
dlg.setControlEnabled("CssLabel", bEnable);
dlg.setControlEnabled("Css", bEnable);
}
}
private class FormattingHandler extends PageHandler {
private final String[] sExportValues = { "convert_all", "ignore_styles", "ignore_hard", "ignore_all" };
private final String[] sListExportValues = { "css1", "css1_hack", "hard_labels" };
@Override protected void setControls(DialogAccess dlg) {
listBoxFromConfig(dlg, "Formatting", "formatting", sExportValues, (short) 0);
listBoxFromConfig(dlg, "FrameFormatting", "frame_formatting", sExportValues, (short) 0);
// OOo does not support styles for sections and tables, hence this simplified variant
dlg.setCheckBoxStateAsBoolean("SectionFormatting",
config.getOption("section_formatting").equals("convert_all") ||
config.getOption("section_formatting").equals("ignore_styles"));
dlg.setCheckBoxStateAsBoolean("TableFormatting",
config.getOption("table_formatting").equals("convert_all") ||
config.getOption("table_formatting").equals("ignore_styles"));
checkBoxFromConfig(dlg, "IgnoreTableDimensions", "ignore_table_dimensions");
listBoxFromConfig(dlg, "ListFormatting", "list_formatting", sListExportValues, (short) 0);
textFieldFromConfig(dlg, "MaxWidth", "max_width");
checkBoxFromConfig(dlg, "SeparateStylesheet", "separate_stylesheet");
}
@Override protected void getControls(DialogAccess dlg) {
listBoxToConfig(dlg, "Formatting", "formatting", sExportValues);
listBoxToConfig(dlg, "FrameFormatting", "frame_formatting", sExportValues);
config.setOption("section_formatting", dlg.getCheckBoxStateAsBoolean("SectionFormatting") ? "convert_all" : "ignore_all");
config.setOption("table_formatting", dlg.getCheckBoxStateAsBoolean("TableFormatting") ? "convert_all" : "ignore_all");
checkBoxToConfig(dlg, "IgnoreTableDimensions", "ignore_table_dimensions");
listBoxToConfig(dlg, "ListFormatting", "list_formatting", sListExportValues);
textFieldToConfig(dlg, "MaxWidth", "max_width");
checkBoxToConfig(dlg, "SeparateStylesheet", "separate_stylesheet");
}
@Override protected boolean handleEvent(DialogAccess dlg, String sMethod) {
return false;
}
}
private class ContentHandler extends PageHandler {
private final String[] sFormulaValues = { "image+starmath", "image+latex", "starmath", "latex" };
@Override protected void setControls(DialogAccess dlg) {
listBoxFromConfig(dlg, "Formulas", "formulas", sFormulaValues, (short) 0);
textFieldFromConfig(dlg, "EndnotesHeading", "endnotes_heading");
textFieldFromConfig(dlg, "FootnotesHeading", "footnotes_heading");
checkBoxFromConfig(dlg, "EmbedSvg", "embed_svg");
checkBoxFromConfig(dlg, "EmbedImg", "embed_img");
}
@Override protected void getControls(DialogAccess dlg) {
listBoxToConfig(dlg, "Formulas", "formulas", sFormulaValues);
textFieldToConfig(dlg, "EndnotesHeading", "endnotes_heading");
textFieldToConfig(dlg, "FootnotesHeading", "footnotes_heading");
checkBoxToConfig(dlg, "EmbedSvg", "embed_svg");
checkBoxToConfig(dlg, "EmbedImg", "embed_img");
}
@Override protected boolean handleEvent(DialogAccess dlg, String sMethod) {
return false;
}
}
private String none2empty(String s) {
return s.equals("(none)") ? "" : s;
}
private String empty2none(String s) {
String t = s.trim();
return t.length()==0 ? "(none)" : t;
}
}

View file

@ -0,0 +1,47 @@
/************************************************************************
*
* Epub3OptionsDialog.java
*
* Copyright: 2002-2016 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-05-05)
*
*/
package org.openoffice.da.comp.writer2xhtml;
import com.sun.star.uno.XComponentContext;
/** This class provides a UNO component which implements a filter UI for the
* EPUB 3 export. In this version the option to include NCX is enabled.
*/
public class Epub3OptionsDialog extends EpubOptionsDialog {
/** The component will be registered under this name.
*/
public static String __serviceName = "org.openoffice.da.writer2xhtml.Epub3OptionsDialog";
/** The component should also have an implementation name.
*/
public static String __implementationName = "org.openoffice.da.comp.writer2xhtml.Epub3OptionsDialog";
/** Create a new Epub3OptionsDialog */
public Epub3OptionsDialog(XComponentContext xContext) {
super(xContext);
}
}

View file

@ -0,0 +1,707 @@
/************************************************************************
*
* EpubMetadataDialog.java
*
* Copyright: 2002-2011 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.2 (2011-07-20)
*
*/
package org.openoffice.da.comp.writer2xhtml;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.openoffice.da.comp.w2lcommon.helper.DialogBase;
import org.openoffice.da.comp.w2lcommon.helper.SimpleDialog;
import writer2latex.util.CSVList;
import writer2latex.util.Misc;
import com.sun.star.awt.XDialog;
import com.sun.star.beans.IllegalTypeException;
import com.sun.star.beans.NotRemoveableException;
import com.sun.star.beans.Property;
import com.sun.star.beans.PropertyExistException;
import com.sun.star.beans.PropertyVetoException;
import com.sun.star.beans.UnknownPropertyException;
import com.sun.star.beans.XPropertyContainer;
import com.sun.star.beans.XPropertySet;
import com.sun.star.document.XDocumentProperties;
import com.sun.star.document.XDocumentPropertiesSupplier;
import com.sun.star.frame.XDesktop;
import com.sun.star.lang.IllegalArgumentException;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.lang.XComponent;
import com.sun.star.ui.dialogs.ExecutableDialogResults;
import com.sun.star.uno.AnyConverter;
import com.sun.star.uno.Exception;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.util.DateTime;
// TODO: Create the UNO helper class DocumentPropertiesAccess
/** This class provides a UNO component which implements a custom metadata editor UI for the EPUB export
*/
public class EpubMetadataDialog extends DialogBase {
// Author data
private class AuthorInfo {
String sName = "";
boolean isCreator = true;
String sRole = "";
}
// Date data
private class DateInfo {
int nDate = 0;
String sEvent = "";
}
// All the user defined properties we handle
private static final String IDENTIFIER="Identifier";
private static final String CREATOR="Creator";
private static final String CONTRIBUTOR="Contributor";
private static final String DATE="Date";
private static final String PUBLISHER="Publisher";
private static final String TYPE="Type";
private static final String FORMAT="Format";
private static final String SOURCE="Source";
private static final String RELATION="Relation";
private static final String COVERAGE="Coverage";
private static final String RIGHTS="Rights";
private static final String[] sRoles = {"", "adp", "ann", "arr", "art", "asn", "aut", "aqt", "aft", "aui", "ant", "bkp",
"clb", "cmm", "dsr", "edt", "ill", "lyr", "mdc", "mus", "nrt", "oth", "pht", "prt", "red", "rev", "spn", "ths", "trc", "trl"};
private static HashMap<String,Short> backRoles;
static {
backRoles = new HashMap<String,Short>();
int nCount = sRoles.length;
for (short i=0; i<nCount; i++) {
backRoles.put(sRoles[i], i);
}
}
// Access to the document properties
private XDocumentProperties xDocumentProperties=null;
private XPropertyContainer xUserProperties=null;
private XPropertySet xUserPropertySet=null;
// Author and date bookkeeping
private Vector<AuthorInfo> authors = new Vector<AuthorInfo>();
private Vector<DateInfo> dates = new Vector<DateInfo>();
// Number formatter
private NumberFormat formatter = new DecimalFormat("00");
// Pattern matcher for dates
Pattern datePattern = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})");
public EpubMetadataDialog(XComponentContext xContext) {
super(xContext);
}
/** The component will be registered under this name.
*/
public static String __serviceName = "org.openoffice.da.writer2xhtml.EpubMetadataDialog";
/** The component should also have an implementation name.
*/
public static String __implementationName = "org.openoffice.da.comp.writer2xhtml.EpubMetadataDialog";
// --------------------------------------------------
// Ensure that the super can find us :-)
@Override public String getDialogLibraryName() {
return "W2XDialogs2";
}
@Override public String getDialogName() {
return "EpubMetadata";
}
// --------------------------------------------------
// Implement the interface XDialogEventHandler
@Override public boolean callHandlerMethod(XDialog xDialog, Object event, String sMethod) {
if (sMethod.equals("UseCustomIdentifierChange")) {
return useCustomIdentifierChange();
}
else if (sMethod.equals("AuthorAddClick")) {
return authorAddclick();
}
else if (sMethod.equals("AuthorModifyClick")) {
return authorModifyclick();
}
else if (sMethod.equals("AuthorDeleteClick")) {
return authorDeleteclick();
}
else if (sMethod.equals("AuthorUpClick")) {
return authorUpclick();
}
else if (sMethod.equals("AuthorDownClick")) {
return authorDownclick();
}
else if (sMethod.equals("DateAddClick")) {
return dateAddClick();
}
else if (sMethod.equals("DateModifyClick")) {
return dateModifyClick();
}
else if (sMethod.equals("DateDeleteClick")) {
return dateDeleteClick();
}
else if (sMethod.equals("DateUpClick")) {
return dateUpClick();
}
else if (sMethod.equals("DateDownClick")) {
return dateDownClick();
}
return false;
}
@Override public String[] getSupportedMethodNames() {
String[] sNames = { "UseCustomIdentifierChange",
"AuthorAddClick", "AuthorModifyClick", "AuthorDeleteClick", "AuthorUpClick", "AuthorDownClick",
"DataAddClick", "DateModifyClick", "DateDeleteClick", "DateUpClick", "DateDownClick"};
return sNames;
}
private boolean useCustomIdentifierChange() {
boolean bEnabled = getCheckBoxStateAsBoolean("UseCustomIdentifier");
setControlEnabled("IdentifierLabel",bEnabled);
setControlEnabled("Identifier",bEnabled);
setControlEnabled("IdentifierTypeLabel",bEnabled);
setControlEnabled("IdentifierType",bEnabled);
return true;
}
private boolean authorAddclick() {
SimpleDialog dialog = new SimpleDialog(xContext,"W2XDialogs2.AuthorDialog");
if (dialog.getDialog()!=null) {
dialog.getControls().setListBoxSelectedItem("Type", (short) 0);
dialog.getControls().setListBoxSelectedItem("Role", (short) 0);
if (dialog.getDialog().execute()==ExecutableDialogResults.OK) {
AuthorInfo author = new AuthorInfo();
author.sName = dialog.getControls().getTextFieldText("Author");
author.sRole = sRoles[dialog.getControls().getListBoxSelectedItem("Role")];
author.isCreator = dialog.getControls().getListBoxSelectedItem("Type")==0;
authors.add(author);
updateAuthorList((short) (authors.size()-1));
}
dialog.getDialog().endExecute();
}
return true;
}
private boolean authorModifyclick() {
short nIndex = getListBoxSelectedItem("Authors");
AuthorInfo author = authors.get(nIndex);
SimpleDialog dialog = new SimpleDialog(xContext,"W2XDialogs2.AuthorDialog");
if (dialog.getDialog()!=null) {
dialog.getControls().setTextFieldText("Author", author.sName);
dialog.getControls().setListBoxSelectedItem("Type", author.isCreator ? (short)0 : (short) 1);
dialog.getControls().setListBoxSelectedItem("Role", backRoles.containsKey(author.sRole)? backRoles.get(author.sRole) : (short)0);
if (dialog.getDialog().execute()==ExecutableDialogResults.OK) {
author.sName = dialog.getControls().getTextFieldText("Author");
author.sRole = sRoles[dialog.getControls().getListBoxSelectedItem("Role")];
author.isCreator = dialog.getControls().getListBoxSelectedItem("Type")==0;
updateAuthorList(nIndex);
}
dialog.getDialog().endExecute();
}
return true;
}
private boolean authorDeleteclick() {
if (authors.size()>0) {
SimpleDialog dialog = new SimpleDialog(xContext,"W2XDialogs2.DeleteDialog");
if (dialog.getDialog()!=null) {
short nIndex = getListBoxSelectedItem("Authors");
String sLabel = dialog.getControls().getLabelText("DeleteLabel");
sLabel = sLabel.replaceAll("%s", authors.get(nIndex).sName);
dialog.getControls().setLabelText("DeleteLabel", sLabel);
if (dialog.getDialog().execute()==ExecutableDialogResults.OK) {
authors.remove(nIndex);
updateAuthorList(nIndex<authors.size() ? (short) nIndex : (short) (nIndex-1));
}
}
}
return true;
}
private boolean authorUpclick() {
short nIndex = getListBoxSelectedItem("Authors");
if (nIndex>0) {
AuthorInfo author = authors.get(nIndex);
authors.set(nIndex, authors.get(nIndex-1));
authors.set(nIndex-1, author);
updateAuthorList((short) (nIndex-1));
}
return true;
}
private boolean authorDownclick() {
short nIndex = getListBoxSelectedItem("Authors");
if (nIndex+1<authors.size()) {
AuthorInfo author = authors.get(nIndex);
authors.set(nIndex, authors.get(nIndex+1));
authors.set(nIndex+1, author);
updateAuthorList((short) (nIndex+1));
}
return true;
}
private boolean dateAddClick() {
SimpleDialog dialog = new SimpleDialog(xContext,"W2XDialogs2.DateDialog");
if (dialog.getDialog()!=null) {
dialog.getControls().setDateFieldValue("Date", datetime2int(xDocumentProperties.getModificationDate()));
if (dialog.getDialog().execute()==ExecutableDialogResults.OK) {
DateInfo date = new DateInfo();
date.nDate = dialog.getControls().getDateFieldValue("Date");
date.sEvent = dialog.getControls().getTextFieldText("Event").trim();
dates.add(date);
updateDateList((short) (dates.size()-1));
}
dialog.getDialog().endExecute();
}
return true;
}
private boolean dateModifyClick() {
short nIndex = getListBoxSelectedItem("Dates");
DateInfo date = dates.get(nIndex);
SimpleDialog dialog = new SimpleDialog(xContext,"W2XDialogs2.DateDialog");
if (dialog.getDialog()!=null) {
dialog.getControls().setDateFieldValue("Date", date.nDate);
dialog.getControls().setTextFieldText("Event", date.sEvent);
if (dialog.getDialog().execute()==ExecutableDialogResults.OK) {
date.nDate = dialog.getControls().getDateFieldValue("Date");
date.sEvent = dialog.getControls().getTextFieldText("Event").trim();
updateDateList(nIndex);
}
dialog.getDialog().endExecute();
}
return true;
}
private boolean dateDeleteClick() {
if (dates.size()>0) {
SimpleDialog dialog = new SimpleDialog(xContext,"W2XDialogs2.DeleteDialog");
if (dialog.getDialog()!=null) {
short nIndex = getListBoxSelectedItem("Dates");
String sLabel = dialog.getControls().getLabelText("DeleteLabel");
sLabel = sLabel.replaceAll("%s", formatDate(dates.get(nIndex).nDate));
dialog.getControls().setLabelText("DeleteLabel", sLabel);
if (dialog.getDialog().execute()==ExecutableDialogResults.OK) {
dates.remove(nIndex);
updateDateList(nIndex<dates.size() ? (short) nIndex : (short) (nIndex-1));
}
}
}
return true;
}
private boolean dateUpClick() {
short nIndex = getListBoxSelectedItem("Dates");
if (nIndex>0) {
DateInfo date = dates.get(nIndex);
dates.set(nIndex, dates.get(nIndex-1));
dates.set(nIndex-1, date);
updateDateList((short) (nIndex-1));
}
return true;
}
private boolean dateDownClick() {
short nIndex = getListBoxSelectedItem("Dates");
if (nIndex+1<dates.size()) {
DateInfo date = dates.get(nIndex);
dates.set(nIndex, dates.get(nIndex+1));
dates.set(nIndex+1, date);
updateDateList((short) (nIndex+1));
}
return true;
}
// --------------------------------------------------
// Get and set properties from and to current document
@Override protected void initialize() {
// Get the document properties
XDesktop xDesktop;
Object desktop;
try {
desktop = xContext.getServiceManager().createInstanceWithContext("com.sun.star.frame.Desktop", xContext);
} catch (Exception e) {
// Failed to get desktop
return;
}
xDesktop = (XDesktop) UnoRuntime.queryInterface(com.sun.star.frame.XDesktop.class, desktop);
XComponent xComponent = xDesktop.getCurrentComponent();
XDocumentPropertiesSupplier xSupplier = (XDocumentPropertiesSupplier) UnoRuntime.queryInterface(XDocumentPropertiesSupplier.class, xComponent);
// Get the document properties (we need several interfaces)
xDocumentProperties = xSupplier.getDocumentProperties();
xUserProperties= xDocumentProperties.getUserDefinedProperties();
xUserPropertySet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xUserProperties);
// Get the custom identifier and set the text fields
String[] sIdentifiers = getProperties(IDENTIFIER,false);
setCheckBoxStateAsBoolean("UseCustomIdentifier",sIdentifiers.length>0);
useCustomIdentifierChange();
if (sIdentifiers.length>0) { // Use the first if we have several...
setTextFieldText("Identifier",getStringValue(sIdentifiers[0]));
setTextFieldText("IdentifierType",getSuffix(sIdentifiers[0]));
}
// Get the authors and set the list box
String[] sCreators = getProperties(CREATOR,false);
for (String sCreator : sCreators) {
AuthorInfo creator = new AuthorInfo();
creator.sName = getStringValue(sCreator);
creator.sRole = getSuffix(sCreator);
creator.isCreator = true;
authors.add(creator);
}
String[] sContributors = getProperties(CONTRIBUTOR,false);
for (String sContributor : sContributors) {
AuthorInfo contributor = new AuthorInfo();
contributor.sName = getStringValue(sContributor);
contributor.sRole = getSuffix(sContributor);
contributor.isCreator = false;
authors.add(contributor);
}
updateAuthorList((short) 0);
// Get the dates and set the list box
String[] sDates = getProperties(DATE,false);
for (String sDate : sDates) {
DateInfo date = new DateInfo();
DateTime dt = getDateValue(sDate);
if (dt!=null) { // We accept either a date
date.nDate = datetime2int(dt);
}
else { // Or a string in the form yyyy-mm-dd
date.nDate = parseDate(getStringValue(sDate));
}
date.sEvent = getSuffix(sDate);
dates.add(date);
}
updateDateList((short) 0);
// Get the standard properties and set the text fields
setTextFieldText("Title",xDocumentProperties.getTitle());
setTextFieldText("Subject",xDocumentProperties.getSubject());
String[] sKeywords = xDocumentProperties.getKeywords();
CSVList keywords = new CSVList(", ");
for (String sKeyword : sKeywords) {
keywords.addValue(sKeyword);
}
setTextFieldText("Keywords",keywords.toString());
setTextFieldText("Description",xDocumentProperties.getDescription());
// Get the simple user properties and set the text fields
readSimpleProperty(PUBLISHER);
readSimpleProperty(TYPE);
readSimpleProperty(FORMAT);
readSimpleProperty(SOURCE);
readSimpleProperty(RELATION);
readSimpleProperty(COVERAGE);
readSimpleProperty(RIGHTS);
}
@Override protected void endDialog() {
// Set the custom identifier from the text fields
String[] sIdentifiers = getProperties(IDENTIFIER,false);
for (String sIdentifier : sIdentifiers) { // Remove old identifier(s)
removeProperty(sIdentifier);
}
if (getCheckBoxStateAsBoolean("UseCustomIdentifier")) {
String sName = IDENTIFIER;
if (getTextFieldText("IdentifierType").trim().length()>0) {
sName+="."+getTextFieldText("IdentifierType").trim();
}
addProperty(sName);
setValue(sName,getTextFieldText("Identifier"));
}
// Set the authors from the list box
String[] sCreators = getProperties(CREATOR,false);
for (String sCreator : sCreators) { // remove old creators
removeProperty(sCreator);
}
String[] sContributors = getProperties(CONTRIBUTOR,false);
for (String sContributor : sContributors) { // remove old contributors
removeProperty(sContributor);
}
int i=0;
for (AuthorInfo author : authors) {
String sName = (author.isCreator ? CREATOR : CONTRIBUTOR)+formatter.format(++i);
if (author.sRole.length()>0) {
sName+="."+author.sRole;
}
addProperty(sName);
setValue(sName,author.sName);
}
// Set the dates from the list box
String[] sDates = getProperties(DATE,false);
for (String sDate : sDates) { // remove old dates
removeProperty(sDate);
}
i=0;
for (DateInfo date : dates) {
String sName = DATE+formatter.format(++i);
if (date.sEvent.length()>0) {
sName+="."+date.sEvent;
}
addProperty(sName);
setValue(sName,formatDate(date.nDate));
// Doesn't work (why not?)
//setValue(sName,int2datetime(date.nDate));
}
// Set the standard properties from the text fields
xDocumentProperties.setTitle(getTextFieldText("Title"));
xDocumentProperties.setSubject(getTextFieldText("Subject"));
String[] sKeywords = getTextFieldText("Keywords").split(",");
for (int j=0; j<sKeywords.length; j++) {
sKeywords[j] = sKeywords[j].trim();
}
xDocumentProperties.setKeywords(sKeywords);
xDocumentProperties.setDescription(getTextFieldText("Description"));
// Set the simple user properties from the text fields
writeSimpleProperty(PUBLISHER);
writeSimpleProperty(TYPE);
writeSimpleProperty(FORMAT);
writeSimpleProperty(SOURCE);
writeSimpleProperty(RELATION);
writeSimpleProperty(COVERAGE);
writeSimpleProperty(RIGHTS);
}
// Get the suffix of a user defined property (portion after fist ., if any)
private String getSuffix(String sPropertyName) {
int nDot = sPropertyName.indexOf(".");
return nDot>-1 ? sPropertyName.substring(nDot+1) : "";
}
// Get all currently defined user properties with a specific name or prefix
private String[] getProperties(String sPrefix, boolean bComplete) {
HashSet<String> names = new HashSet<String>();
Property[] xProps = xUserPropertySet.getPropertySetInfo().getProperties();
for (Property prop : xProps) {
String sName = prop.Name;
String sLCName = sName.toLowerCase();
String sLCPrefix = sPrefix.toLowerCase();
if ((bComplete && sLCName.equals(sLCPrefix)) || (!bComplete && sLCName.startsWith(sLCPrefix))) {
names.add(sName);
}
}
return Misc.sortStringSet(names);
}
// Add a user property
private void addProperty(String sName) {
try {
xUserProperties.addProperty(sName, (short) 128, ""); // 128 means removeable, last parameter is default value
} catch (PropertyExistException e) {
} catch (IllegalTypeException e) {
} catch (IllegalArgumentException e) {
}
}
// Delete a user property
private void removeProperty(String sName) {
try {
xUserProperties.removeProperty(sName);
} catch (UnknownPropertyException e) {
} catch (NotRemoveableException e) {
}
}
// Set the value of a user property (failing silently if the property does not exist)
private void setValue(String sName, Object value) {
try {
xUserPropertySet.setPropertyValue(sName, value);
} catch (UnknownPropertyException e) {
} catch (PropertyVetoException e) {
} catch (IllegalArgumentException e) {
} catch (WrappedTargetException e) {
}
}
// Get the string value of a user property (returning null if the property does not exist)
private String getStringValue(String sName) {
Object value = getValue(sName);
if (value!=null && AnyConverter.isString(value)) {
try {
return AnyConverter.toString(value);
} catch (IllegalArgumentException e) {
return null;
}
}
return null;
}
private DateTime getDateValue(String sName) {
Object value = getValue(sName);
if (value!=null && value instanceof DateTime) {
return (DateTime) value;
}
return null;
}
// Get the value of a user property (returning null if the property does not exist)
private Object getValue(String sName) {
try {
return xUserPropertySet.getPropertyValue(sName);
} catch (UnknownPropertyException e) {
return null;
} catch (WrappedTargetException e) {
return null;
}
}
private void updateAuthorList(short nItem) {
int nCount = authors.size();
if (nCount>0) {
String[] sAuthors = new String[nCount];
for (int i=0; i<nCount; i++) {
AuthorInfo author = authors.get(i);
sAuthors[i] = author.sName
+" ("
+(author.isCreator ? "creator":"contributor")
+(author.sRole.length()>0 ? ", "+author.sRole : "")
+")";
}
setListBoxStringItemList("Authors", sAuthors);
setListBoxSelectedItem("Authors",nItem);
setControlEnabled("Authors", true);
}
else { // Display the fall-back author
String[] sAuthors = new String[1];
//sAuthors[0] = xDocumentProperties.getAuthor()+" (default creator)";
sAuthors[0] = xDocumentProperties.getModifiedBy()+" (default creator)";
setListBoxStringItemList("Authors", sAuthors);
setControlEnabled("Authors", false);
}
setControlEnabled("ModifyAuthorButton",nCount>0);
setControlEnabled("DeleteAuthorButton",nCount>0);
setControlEnabled("AuthorUpButton",nCount>1);
setControlEnabled("AuthorDownButton",nCount>1);
}
private void updateDateList(short nItem) {
int nCount = dates.size();
if (nCount>0) {
String[] sDates = new String[nCount];
for (int i=0; i<nCount; i++) {
DateInfo date = dates.get(i);
sDates[i] = formatDate(date.nDate);
if (date.sEvent.length()>0) {
sDates[i]+=" (" + date.sEvent + ")";
}
}
setListBoxStringItemList("Dates", sDates);
setListBoxSelectedItem("Dates",nItem);
setControlEnabled("Dates", true);
}
else { // Display the fall-back date
String[] sDates = new String[1];
sDates[0] = formatDate(datetime2int(xDocumentProperties.getModificationDate()))+" (default date)";
setListBoxStringItemList("Dates", sDates);
setControlEnabled("Dates", false);
}
setControlEnabled("ModifyDateButton",nCount>0);
setControlEnabled("DeleteDateButton",nCount>0);
setControlEnabled("DateUpButton",nCount>1);
setControlEnabled("DateDownButton",nCount>1);
}
private void readSimpleProperty(String sName) {
String[] sNames = getProperties(sName,true);
if (sNames.length>0) {
String sValue = getStringValue(sNames[0]);
if (sValue!=null) {
setTextFieldText(sName, sValue);
}
}
}
private void writeSimpleProperty(String sName) {
String[] sOldNames = getProperties(sName,true);
for (String sOldName : sOldNames) {
removeProperty(sOldName);
}
String sValue = getTextFieldText(sName);
if (sValue.length()>0) {
addProperty(sName);
setValue(sName,sValue);
}
}
// Date fields uses integers for dates (format yyyymmdd)
// Document properties uses com.sun.star.util.DateTime
// Also dates should be formatted as yyyy-mm-dd as strings
// Thus we need a few conversion methods
// Format a integer date as yyyy-mm-dd
private String formatDate(int nDate) {
String sDate = Integer.toString(nDate);
if (sDate.length()==8) {
return sDate.substring(0,4)+"-"+sDate.substring(4, 6)+"-"+sDate.substring(6);
}
else {
return "???";
}
}
// Parse a string as a date in the format yyyy-mm-dd (returning 0 on failure)
private int parseDate(String sDate) {
Matcher matcher = datePattern.matcher(sDate);
if (matcher.matches()) {
return Misc.getPosInteger(matcher.group(1)+matcher.group(2)+matcher.group(3),0);
}
return 0;
}
// Convert an integer to com.sun.star.util.DateTime
/*private DateTime int2datetime(int nDate) {
DateTime date = new DateTime();
date.Year = (short) (nDate/10000);
date.Month = (short) ((nDate%10000)/100);
date.Day = (short) (nDate%100);
return date;
}*/
// Convert a com.sun.star.util.DateTime to integer
private int datetime2int(DateTime date) {
return 10000*date.Year+100*date.Month+date.Day;
}
}

View file

@ -0,0 +1,348 @@
/************************************************************************
*
* EpubOptionsDialog.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-04-28)
*
*/
package org.openoffice.da.comp.writer2xhtml;
import java.awt.GraphicsEnvironment;
import com.sun.star.awt.XDialog;
import com.sun.star.beans.XPropertySet;
import com.sun.star.lang.XComponent;
import com.sun.star.ui.dialogs.XExecutableDialog;
import com.sun.star.uno.Exception;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import org.openoffice.da.comp.w2lcommon.helper.PropertyHelper;
import org.openoffice.da.comp.w2lcommon.filter.OptionsDialogBase;
/** This class provides a UNO component which implements a filter UI for the
* EPUB export
*/
public class EpubOptionsDialog extends OptionsDialogBase {
/** The component will be registered under this name.
*/
public static String __serviceName = "org.openoffice.da.writer2xhtml.EpubOptionsDialog";
/** The component should also have an implementation name.
*/
public static String __implementationName = "org.openoffice.da.comp.writer2xhtml.EpubOptionsDialog";
@Override public String getDialogLibraryName() { return "W2XDialogs2"; }
/** Return the name of the dialog within the library
*/
@Override public String getDialogName() { return "EpubOptions"; }
/** Return the name of the registry path
*/
@Override public String getRegistryPath() {
return "/org.openoffice.da.Writer2xhtml.Options/EpubOptions";
}
/** Create a new EpubOptionsDialog */
public EpubOptionsDialog(XComponentContext xContext) {
super(xContext);
xMSF = W2XRegistration.xMultiServiceFactory;
}
/** Load settings from the registry to the dialog */
@Override protected void loadSettings(XPropertySet xProps) {
// Style
loadConfig(xProps);
int nScaling = loadNumericOption(xProps, "Scaling");
if (nScaling<=1) { // Workaround for an obscure bug in the extension manager
setNumericFieldValue("Scaling",100);
}
int nColumnScaling = loadNumericOption(xProps, "ColumnScaling");
if (nColumnScaling<=1) {
setNumericFieldValue("ColumnScaling",100);
}
loadCheckBoxOption(xProps, "RelativeFontSize");
loadNumericOption(xProps, "FontScaling");
int nFontScaling = loadNumericOption(xProps, "FontScaling");
if (nFontScaling<=1) {
setNumericFieldValue("FontScaling",100);
}
loadCheckBoxOption(xProps, "RelativeFontSize");
loadCheckBoxOption(xProps, "UseDefaultFont");
loadComboBoxOption(xProps, "DefaultFontName");
loadCheckBoxOption(xProps, "ConvertToPx");
loadListBoxOption(xProps, "ImageSize");
// Fill the font name list with all installed fonts
setListBoxStringItemList("DefaultFontName",
GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames());
// AutoCorrect
loadCheckBoxOption(xProps, "IgnoreHardLineBreaks");
loadCheckBoxOption(xProps, "IgnoreEmptyParagraphs");
loadCheckBoxOption(xProps, "IgnoreDoubleSpaces");
// Special content
loadCheckBoxOption(xProps, "DisplayHiddenText");
loadCheckBoxOption(xProps, "Notes");
// Document division
loadListBoxOption(xProps, "SplitLevel");
loadListBoxOption(xProps, "PageBreakSplit");
loadCheckBoxOption(xProps, "UseImageSplit");
loadNumericOption(xProps, "ImageSplit");
loadCheckBoxOption(xProps, "CoverImage");
loadCheckBoxOption(xProps, "UseSplitAfter");
loadNumericOption(xProps, "SplitAfter");
// Navigation table
loadListBoxOption(xProps, "ExternalTocDepth");
loadCheckBoxOption(xProps, "IncludeToc");
loadCheckBoxOption(xProps, "IncludeNCX");
updateLockedOptions();
enableControls();
}
/** Save settings from the dialog to the registry and create FilterData */
@Override protected void saveSettings(XPropertySet xProps, PropertyHelper helper) {
// Style
short nConfig = saveConfig(xProps, helper);
switch (nConfig) {
case 0: helper.put("ConfigURL","*default.xml"); break;
case 1: helper.put("ConfigURL","$(user)/writer2xhtml.xml");
helper.put("AutoCreate","true");
helper.put("TemplateURL", "$(user)/writer2xhtml-template.xhtml");
helper.put("StyleSheetURL", "$(user)/writer2xhtml-styles.css");
helper.put("ResourceURL", "$(user)/writer2xhtml-resources");
}
saveNumericOptionAsPercentage(xProps, helper, "Scaling", "scaling");
saveNumericOptionAsPercentage(xProps, helper, "ColumnScaling", "column_scaling");
saveCheckBoxOption(xProps, helper, "RelativeFontSize", "relative_font_size");
saveNumericOptionAsPercentage(xProps, helper, "FontScaling", "font_scaling");
saveCheckBoxOption(xProps, helper, "UseDefaultFont", "use_default_font");
saveTextFieldOption(xProps, helper, "DefaultFontName", "default_font_name");
saveCheckBoxOption(xProps, helper, "ConvertToPx", "convert_to_px");
saveListBoxOption(xProps, "ImageSize");
switch (getListBoxSelectedItem("ImageSize")) {
case 0: helper.put("image_size", "absolute"); break;
case 1: helper.put("image_size", "relative"); break;
case 2: helper.put("image_size", "none");
}
// AutoCorrect
saveCheckBoxOption(xProps, helper, "IgnoreHardLineBreaks", "ignore_hard_line_breaks");
saveCheckBoxOption(xProps, helper, "IgnoreEmptyParagraphs", "ignore_empty_paragraphs");
saveCheckBoxOption(xProps, helper, "IgnoreDoubleSpaces", "ignore_double_spaces");
// Special content
saveCheckBoxOption(xProps, helper, "DisplayHiddenText", "display_hidden_text");
saveCheckBoxOption(xProps, helper, "Notes", "notes");
// Document division
short nSplitLevel = saveListBoxOption(xProps, "SplitLevel");
if (!isLocked("split_level")) {
helper.put("split_level",Integer.toString(nSplitLevel));
}
short nPageBreakSplit = saveListBoxOption(xProps, "PageBreakSplit");
if (!isLocked("page_break_split")) {
switch (nPageBreakSplit) {
case 0: helper.put("page_break_split","none"); break;
case 1: helper.put("page_break_split", "styles"); break;
case 2: helper.put("page_break_split", "explicit"); break;
case 3: helper.put("page_break_split", "all");
}
}
boolean bUseImageSplit = saveCheckBoxOption(xProps, "UseImageSplit");
int nImageSplit = saveNumericOption(xProps, "ImageSplit");
if (!isLocked("image_split")) {
if (bUseImageSplit) {
helper.put("image_split", nImageSplit+"%");
}
else {
helper.put("image_split", "none");
}
}
saveCheckBoxOption(xProps, helper, "CoverImage", "cover_image");
boolean bUseSplitAfter = saveCheckBoxOption(xProps, "UseSplitAfter");
int nSplitAfter = saveNumericOption(xProps, "SplitAfter");
if (!isLocked("split_after")) {
if (bUseSplitAfter) {
helper.put("split_after", Integer.toString(nSplitAfter));
}
else {
helper.put("split_after", "0");
}
}
// Navigation table
short nExternalTocDepth = saveListBoxOption(xProps, "ExternalTocDepth");
helper.put("external_toc_depth", Integer.toString(nExternalTocDepth+1));
saveCheckBoxOption(xProps, helper, "IncludeToc", "include_toc");
saveCheckBoxOption(xProps, helper, "IncludeNCX", "include_ncx");
}
// Implement XDialogEventHandler
@Override public boolean callHandlerMethod(XDialog xDialog, Object event, String sMethod) {
if (sMethod.equals("ConfigChange")) {
updateLockedOptions();
enableControls();
}
else if (sMethod.equals("RelativeFontSizeChange")) {
relativeFontSizeChange();
}
else if (sMethod.equals("UseDefaultFontChange")) {
useDefaultFontChange();
}
else if (sMethod.equals("EditMetadataClick")) {
editMetadataClick();
}
else if (sMethod.equals("UseImageSplitChange")) {
useImageSplitChange();
}
else if (sMethod.equals("UseSplitAfterChange")) {
useSplitAfterChange();
}
return true;
}
@Override public String[] getSupportedMethodNames() {
String[] sNames = { "ConfigChange", "RelativeFontSizeChange", "UseDefaultFontChange", "EditMetadataClick",
"UseImageSplitChange", "UseSplitAfterChange" };
return sNames;
}
private void enableControls() {
// Style
setControlEnabled("ScalingLabel",!isLocked("scaling"));
setControlEnabled("Scaling",!isLocked("scaling"));
setControlEnabled("ColumnScalingLabel",!isLocked("column_scaling"));
setControlEnabled("ColumnScaling",!isLocked("column_scaling"));
boolean bRelativeFontSize = getCheckBoxStateAsBoolean("RelativeFontSize");
setControlEnabled("RelativeFontSize",!isLocked("relative_font_size"));
setControlEnabled("FontScalingLabel", !isLocked("font_scaling") && bRelativeFontSize);
setControlEnabled("FontScaling",!isLocked("font_scaling") && bRelativeFontSize);
setControlEnabled("FontScalingPercentLabel", !isLocked("font_scaling") && bRelativeFontSize);
boolean bUseDefaultFont = getCheckBoxStateAsBoolean("UseDefaultFont");
setControlEnabled("UseDefaultFont",!isLocked("use_default_font"));
setControlEnabled("DefaultFontNameLabel",!isLocked("default_font_name") && bUseDefaultFont);
setControlEnabled("DefaultFontName",!isLocked("default_font_name") && bUseDefaultFont);
setControlEnabled("ConvertToPx",!isLocked("convert_to_px"));
setControlEnabled("ImageSize",!isLocked("image_size"));
// AutoCorrect
setControlEnabled("IgnoreHardLineBreaks",!isLocked("ignore_hard_line_breaks"));
setControlEnabled("IgnoreEmptyParagraphs",!isLocked("ignore_empty_paragraphs"));
setControlEnabled("IgnoreDoubleSpaces",!isLocked("ignore_double_spaces"));
// Special content
setControlEnabled("DisplayHiddenText",!isLocked("display_hidden_text"));
setControlEnabled("Notes",!isLocked("notes"));
// Document division
setControlEnabled("SplitLevelLabel",!isLocked("split_level"));
setControlEnabled("SplitLevel",!isLocked("split_level"));
setControlEnabled("PageBreakSplitLabel",!isLocked("page_break_split"));
setControlEnabled("PageBreakSplit",!isLocked("page_break_split"));
boolean bUseImageSplit = getCheckBoxStateAsBoolean("UseImageSplit");
setControlEnabled("UseImageSplit",!isLocked("image_split"));
setControlEnabled("ImageSplitLabel",!isLocked("image_split") && bUseImageSplit);
setControlEnabled("ImageSplit",!isLocked("image_split") && bUseImageSplit);
setControlEnabled("ImageSplitPercentLabel",!isLocked("image_split") && bUseImageSplit);
setControlEnabled("CoverImage", !isLocked("cover_image"));
boolean bUseSplitAfter = getCheckBoxStateAsBoolean("UseSplitAfter");
setControlEnabled("UseSplitAfter",!isLocked("split_after"));
setControlEnabled("SplitAfterLabel",!isLocked("split_after") && bUseSplitAfter);
setControlEnabled("SplitAfter",!isLocked("split_after") && bUseSplitAfter);
// Navigation table
setControlEnabled("ExternalTocDepthLabel", !isLocked("external_toc_depth"));
setControlEnabled("ExternalTocDepth", !isLocked("external_toc_depth"));
setControlEnabled("IncludeToc", !isLocked("include_toc"));
setControlEnabled("IncludeNCX", (this instanceof Epub3OptionsDialog) && !isLocked("include_ncx"));
}
private void relativeFontSizeChange() {
if (!isLocked("font_scaling")) {
boolean bState = getCheckBoxStateAsBoolean("RelativeFontSize");
setControlEnabled("FontScalingLabel", bState);
setControlEnabled("FontScaling", bState);
setControlEnabled("FontScalingPercentLabel", bState);
}
}
private void useDefaultFontChange() {
if (!isLocked("default_font_name")) {
boolean bState = getCheckBoxStateAsBoolean("UseDefaultFont");
setControlEnabled("DefaultFontNameLabel", bState);
setControlEnabled("DefaultFontName", bState);
}
}
private void editMetadataClick() {
Object dialog;
try {
dialog = xContext.getServiceManager().createInstanceWithContext("org.openoffice.da.writer2xhtml.EpubMetadataDialog", xContext);
XExecutableDialog xDialog = (XExecutableDialog) UnoRuntime.queryInterface(XExecutableDialog.class, dialog);
xDialog.execute();
// Dispose the dialog after execution (to free up the memory)
XComponent xComponent = (XComponent) UnoRuntime.queryInterface(XComponent.class, dialog);
if (xComponent!=null) {
xComponent.dispose();
}
} catch (Exception e) {
// Failed to get dialog
}
}
private void useImageSplitChange() {
if (!isLocked("image_split")) {
boolean bEnable = getCheckBoxStateAsBoolean("UseImageSplit");
setControlEnabled("ImageSplitLabel",bEnable);
setControlEnabled("ImageSplit",bEnable);
setControlEnabled("ImageSplitPercentLabel",bEnable);
}
}
private void useSplitAfterChange() {
if (!isLocked("split_after")) {
boolean bState = getCheckBoxStateAsBoolean("UseSplitAfter");
setControlEnabled("SplitAfterLabel",bState);
setControlEnabled("SplitAfter",bState);
}
}
}

View file

@ -0,0 +1,261 @@
/************************************************************************
*
* ToolbarSettingsDialog.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-04-05)
*
*/
package org.openoffice.da.comp.writer2xhtml;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import com.sun.star.awt.XContainerWindowEventHandler;
import com.sun.star.awt.XDialog;
import com.sun.star.awt.XWindow;
import com.sun.star.beans.XPropertySet;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.uno.AnyConverter;
import com.sun.star.uno.Exception;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.util.XChangesBatch;
import com.sun.star.lib.uno.helper.WeakBase;
import org.openoffice.da.comp.w2lcommon.helper.DialogAccess;
import org.openoffice.da.comp.w2lcommon.helper.FilePicker;
import org.openoffice.da.comp.w2lcommon.helper.RegistryHelper;
import org.openoffice.da.comp.w2lcommon.helper.XPropertySetHelper;
/** This class provides a uno component which implements the configuration
* of the writer2xhtml toolbar
*/
public final class ToolbarSettingsDialog
extends WeakBase
implements XServiceInfo, XContainerWindowEventHandler {
public static final String REGISTRY_PATH = "/org.openoffice.da.Writer2xhtml.toolbar.ToolbarOptions/Settings";
private XComponentContext xContext;
private FilePicker filePicker;
/** The component will be registered under this name.
*/
public static String __serviceName = "org.openoffice.da.writer2xhtml.ToolbarSettingsDialog";
/** The component should also have an implementation name.
*/
public static String __implementationName = "org.openoffice.da.comp.writer2xhtml.ToolbarSettingsDialog";
/** Create a new ToolbarSettingsDialog */
public ToolbarSettingsDialog(XComponentContext xContext) {
this.xContext = xContext;
filePicker = new FilePicker(xContext);
}
// Implement XContainerWindowEventHandler
public boolean callHandlerMethod(XWindow xWindow, Object event, String sMethod)
throws com.sun.star.lang.WrappedTargetException {
XDialog xDialog = (XDialog)UnoRuntime.queryInterface(XDialog.class, xWindow);
DialogAccess dlg = new DialogAccess(xDialog);
try {
if (sMethod.equals("external_event") ){
return handleExternalEvent(dlg, event);
}
else if (sMethod.equals("XhtmlFormatChange")) {
return true;
}
else if (sMethod.equals("XhtmlViewChange")) {
return xhtmlViewChange(dlg);
}
else if (sMethod.equals("XhtmlBrowseClick")) {
return xhtmlBrowseClick(dlg);
}
else if (sMethod.equals("EpubFormatChange")) {
return true;
}
else if (sMethod.equals("EpubViewChange")) {
return epubViewChange(dlg);
}
else if (sMethod.equals("EpubBrowseClick")) {
return epubBrowseClick(dlg);
}
}
catch (com.sun.star.uno.RuntimeException e) {
throw e;
}
catch (com.sun.star.uno.Exception e) {
throw new com.sun.star.lang.WrappedTargetException(sMethod, this, e);
}
return false;
}
public String[] getSupportedMethodNames() {
String[] sNames = { "external_event", "XhtmlFormatChange", "XhtmlViewChange", "XhtmlBrowseClick",
"EpupFormatChange", "EpubViewChange", "EpubBrowseClick" };
return sNames;
}
// Implement the interface XServiceInfo
public boolean supportsService(String sServiceName) {
return sServiceName.equals(__serviceName);
}
public String getImplementationName() {
return __implementationName;
}
public String[] getSupportedServiceNames() {
String[] sSupportedServiceNames = { __serviceName };
return sSupportedServiceNames;
}
// Private stuff
private boolean handleExternalEvent(DialogAccess dlg, Object aEventObject)
throws com.sun.star.uno.Exception {
try {
String sMethod = AnyConverter.toString(aEventObject);
if (sMethod.equals("ok")) {
saveConfiguration(dlg);
return true;
} else if (sMethod.equals("back") || sMethod.equals("initialize")) {
loadConfiguration(dlg);
enableXhtmlExecutable(dlg);
enableEpubExecutable(dlg);
return true;
}
}
catch (com.sun.star.lang.IllegalArgumentException e) {
throw new com.sun.star.lang.IllegalArgumentException(
"Method external_event requires a string in the event object argument.", this,(short) -1);
}
return false;
}
private void loadConfiguration(DialogAccess dlg) {
RegistryHelper registry = new RegistryHelper(xContext);
try {
Object view = registry.getRegistryView(REGISTRY_PATH, false);
XPropertySet xProps = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class,view);
dlg.setListBoxSelectedItem("XhtmlFormat",
XPropertySetHelper.getPropertyValueAsShort(xProps, "XhtmlFormat"));
dlg.setListBoxSelectedItem("XhtmlView",
XPropertySetHelper.getPropertyValueAsShort(xProps, "XhtmlView"));
dlg.setTextFieldText("XhtmlExecutable",
XPropertySetHelper.getPropertyValueAsString(xProps, "XhtmlExecutable"));
dlg.setListBoxSelectedItem("EpubFormat",
XPropertySetHelper.getPropertyValueAsShort(xProps, "EpubFormat"));
dlg.setListBoxSelectedItem("EpubView",
XPropertySetHelper.getPropertyValueAsShort(xProps, "EpubView"));
dlg.setTextFieldText("EpubExecutable",
XPropertySetHelper.getPropertyValueAsString(xProps, "EpubExecutable"));
} catch (Exception e) {
// Failed to get registry view
}
}
private void saveConfiguration(DialogAccess dlg) {
RegistryHelper registry = new RegistryHelper(xContext);
try {
Object view = registry.getRegistryView(REGISTRY_PATH, true);
XPropertySet xProps = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class,view);
XPropertySetHelper.setPropertyValue(xProps, "XhtmlFormat", dlg.getListBoxSelectedItem("XhtmlFormat"));
XPropertySetHelper.setPropertyValue(xProps, "XhtmlView", dlg.getListBoxSelectedItem("XhtmlView"));
XPropertySetHelper.setPropertyValue(xProps, "XhtmlExecutable", dlg.getTextFieldText("XhtmlExecutable"));
XPropertySetHelper.setPropertyValue(xProps, "EpubFormat", dlg.getListBoxSelectedItem("EpubFormat"));
XPropertySetHelper.setPropertyValue(xProps, "EpubView", dlg.getListBoxSelectedItem("EpubView"));
XPropertySetHelper.setPropertyValue(xProps, "EpubExecutable", dlg.getTextFieldText("EpubExecutable"));
// Commit registry changes
XChangesBatch xUpdateContext = (XChangesBatch)
UnoRuntime.queryInterface(XChangesBatch.class,view);
try {
xUpdateContext.commitChanges();
}
catch (Exception e) {
// ignore
}
registry.disposeRegistryView(view);
}
catch (Exception e) {
// Failed to get registry view
}
}
private boolean xhtmlViewChange(DialogAccess dlg) {
enableXhtmlExecutable(dlg);
return true;
}
private void enableXhtmlExecutable(DialogAccess dlg) {
int nItem = dlg.getListBoxSelectedItem("XhtmlView");
dlg.setControlEnabled("XhtmlExecutable", nItem==2);
dlg.setControlEnabled("XhtmlBrowseButton", nItem==2);
}
private boolean xhtmlBrowseClick(DialogAccess dlg) {
browseForExecutable(dlg,"XhtmlExecutable");
return true;
}
private boolean epubViewChange(DialogAccess dlg) {
enableEpubExecutable(dlg);
return true;
}
private void enableEpubExecutable(DialogAccess dlg) {
int nItem = dlg.getListBoxSelectedItem("EpubView");
dlg.setControlEnabled("EpubExecutable", nItem==2);
dlg.setControlEnabled("EpubBrowseButton", nItem==2);
}
private boolean epubBrowseClick(DialogAccess dlg) {
browseForExecutable(dlg,"EpubExecutable");
return true;
}
private boolean browseForExecutable(DialogAccess dlg, String sControlName) {
String sPath = filePicker.getPath();
if (sPath!=null) {
try {
dlg.setComboBoxText(sControlName, new File(new URI(sPath)).getCanonicalPath());
}
catch (IOException e) {
}
catch (URISyntaxException e) {
}
}
return true;
}
}

View file

@ -0,0 +1,54 @@
/************************************************************************
*
* W2XExportFilter.java
*
* Copyright: 2002-2014 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2014-10-06)
*
*/
package org.openoffice.da.comp.writer2xhtml;
import com.sun.star.uno.XComponentContext;
import org.openoffice.da.comp.w2lcommon.filter.ExportFilterBase;
/** This class implements the xhtml export filter component
*/
public class W2XExportFilter extends ExportFilterBase {
/** Service name for the component */
public static final String __serviceName = "org.openoffice.da.comp.writer2xhtml.W2XExportFilter";
/** Implementation name for the component */
public static final String __implementationName = "org.openoffice.da.comp.writer2xhtml.W2XExportFilter";
/** Filter name to include in error messages */
public final String __displayName = "Writer2xhtml";
public W2XExportFilter(XComponentContext xComponentContext1) {
super(xComponentContext1);
}
}

View file

@ -0,0 +1,166 @@
/************************************************************************
*
* W2XRegistration.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-04-28)
*
*/
package org.openoffice.da.comp.writer2xhtml;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.lang.XSingleServiceFactory;
import com.sun.star.registry.XRegistryKey;
import com.sun.star.comp.loader.FactoryHelper;
/** This class provides a static method to instantiate our uno components
* on demand (__getServiceFactory()), and a static method to give
* information about the components (__writeRegistryServiceInfo()).
* Furthermore, it saves the XMultiServiceFactory provided to the
* __getServiceFactory method for future reference by the componentes.
*/
public class W2XRegistration {
public static XMultiServiceFactory xMultiServiceFactory;
/**
* Returns a factory for creating the service.
* This method is called by the <code>JavaLoader</code>
*
* @return returns a <code>XSingleServiceFactory</code> for creating the
* component
*
* @param implName the name of the implementation for which a
* service is desired
* @param multiFactory the service manager to be used if needed
* @param regKey the registryKey
*
* @see com.sun.star.comp.loader.JavaLoader
*/
public static XSingleServiceFactory __getServiceFactory(String implName,
XMultiServiceFactory multiFactory, XRegistryKey regKey) {
xMultiServiceFactory = multiFactory;
XSingleServiceFactory xSingleServiceFactory = null;
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,
regKey);
}
else if (implName.equals(BatchConverter.__implementationName) ) {
xSingleServiceFactory = FactoryHelper.getServiceFactory(BatchConverter.class,
BatchConverter.__serviceName,
multiFactory,
regKey);
}
else if (implName.equals(XhtmlOptionsDialog.__implementationName)) {
xSingleServiceFactory = FactoryHelper.getServiceFactory(XhtmlOptionsDialog.class,
XhtmlOptionsDialog.__serviceName,
multiFactory,
regKey);
}
else if (implName.equals(XhtmlOptionsDialogMath.__implementationName)) {
xSingleServiceFactory = FactoryHelper.getServiceFactory(XhtmlOptionsDialogMath.class,
XhtmlOptionsDialogMath.__serviceName,
multiFactory,
regKey);
}
else if (implName.equals(XhtmlOptionsDialogCalc.__implementationName)) {
xSingleServiceFactory = FactoryHelper.getServiceFactory(XhtmlOptionsDialogCalc.class,
XhtmlOptionsDialogCalc.__serviceName,
multiFactory,
regKey);
}
else if (implName.equals(EpubOptionsDialog.__implementationName)) {
xSingleServiceFactory = FactoryHelper.getServiceFactory(EpubOptionsDialog.class,
EpubOptionsDialog.__serviceName,
multiFactory,
regKey);
}
else if (implName.equals(Epub3OptionsDialog.__implementationName)) {
xSingleServiceFactory = FactoryHelper.getServiceFactory(Epub3OptionsDialog.class,
Epub3OptionsDialog.__serviceName,
multiFactory,
regKey);
}
else if (implName.equals(EpubMetadataDialog.__implementationName)) {
xSingleServiceFactory = FactoryHelper.getServiceFactory(EpubMetadataDialog.class,
EpubMetadataDialog.__serviceName,
multiFactory,
regKey);
}
else if (implName.equals(ConfigurationDialog.__implementationName)) {
xSingleServiceFactory = FactoryHelper.getServiceFactory(ConfigurationDialog.class,
ConfigurationDialog.__serviceName,
multiFactory,
regKey);
}
else if (implName.equals(ToolbarSettingsDialog.__implementationName)) {
xSingleServiceFactory = FactoryHelper.getServiceFactory(ToolbarSettingsDialog.class,
ToolbarSettingsDialog.__serviceName,
multiFactory,
regKey);
}
return xSingleServiceFactory;
}
/**
* Writes the service information into the given registry key.
* This method is called by the <code>JavaLoader</code>
* <p>
* @return returns true if the operation succeeded
* @param regKey the registryKey
* @see com.sun.star.comp.loader.JavaLoader
*/
public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) {
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,
XhtmlOptionsDialog.__serviceName, regKey) &
FactoryHelper.writeRegistryServiceInfo(XhtmlOptionsDialogMath.__implementationName,
XhtmlOptionsDialogMath.__serviceName, regKey) &
FactoryHelper.writeRegistryServiceInfo(XhtmlOptionsDialogCalc.__implementationName,
XhtmlOptionsDialogCalc.__serviceName, regKey) &
FactoryHelper.writeRegistryServiceInfo(EpubOptionsDialog.__implementationName,
EpubOptionsDialog.__serviceName, regKey) &
FactoryHelper.writeRegistryServiceInfo(Epub3OptionsDialog.__implementationName,
Epub3OptionsDialog.__serviceName, regKey) &
FactoryHelper.writeRegistryServiceInfo(EpubMetadataDialog.__implementationName,
EpubMetadataDialog.__serviceName, regKey) &
FactoryHelper.writeRegistryServiceInfo(ConfigurationDialog.__implementationName,
ConfigurationDialog.__serviceName, regKey) &
FactoryHelper.writeRegistryServiceInfo(ToolbarSettingsDialog.__implementationName,
ToolbarSettingsDialog.__serviceName, regKey);
}
}

View file

@ -0,0 +1,209 @@
/************************************************************************
*
* Writer2xhtml.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-04-05)
*
*/
package org.openoffice.da.comp.writer2xhtml;
// TODO: Create common base for dispatcher classes
import com.sun.star.beans.XPropertySet;
import com.sun.star.frame.XFrame;
import com.sun.star.lang.XComponent;
import com.sun.star.lib.uno.helper.WeakBase;
import com.sun.star.ui.dialogs.XExecutableDialog;
import com.sun.star.uno.Exception;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import org.openoffice.da.comp.w2lcommon.filter.UNOPublisher.TargetFormat;
import org.openoffice.da.comp.w2lcommon.helper.RegistryHelper;
import org.openoffice.da.comp.w2lcommon.helper.XPropertySetHelper;
/** 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:";
// From constructor+initialization
private final XComponentContext m_xContext;
private XFrame m_xFrame;
private XhtmlUNOPublisher unoPublisher = null;
// Global data
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 };
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]);
}
}
// 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;
else if ( aURL.Path.compareTo("EditEPUBDocumentProperties") == 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 ) {
if ( aURL.Path.compareTo("PublishAsXHTML") == 0 ) {
publishAsXhtml();
return;
}
else if ( aURL.Path.compareTo("PublishAsEPUB") == 0 ) {
publishAsEpub();
return;
}
else if ( aURL.Path.compareTo("EditEPUBDocumentProperties") == 0 ) {
editDocumentProperties();
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 editDocumentProperties() {
Object dialog;
try {
dialog = m_xContext.getServiceManager().createInstanceWithContext("org.openoffice.da.writer2xhtml.EpubMetadataDialog", m_xContext);
XExecutableDialog xDialog = (XExecutableDialog) UnoRuntime.queryInterface(XExecutableDialog.class, dialog);
xDialog.execute();
// Dispose the dialog after execution (to free up the memory)
XComponent xComponent = (XComponent) UnoRuntime.queryInterface(XComponent.class, dialog);
if (xComponent!=null) {
xComponent.dispose();
}
} catch (Exception e) {
// Failed to get dialog
}
}
private void publishAsXhtml() {
RegistryHelper registry = new RegistryHelper(m_xContext);
try {
Object view = registry.getRegistryView(ToolbarSettingsDialog.REGISTRY_PATH, false);
XPropertySet xProps = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class,view);
short nXhtmlFormat = XPropertySetHelper.getPropertyValueAsShort(xProps, "XhtmlFormat");
switch (nXhtmlFormat) {
case 0: publish(TargetFormat.xhtml); break;
case 1: publish(TargetFormat.xhtml11); break;
case 2: publish(TargetFormat.xhtml_mathml); break;
case 3: publish(TargetFormat.html5);
}
} catch (Exception e) {
// Failed to get registry view
}
}
private void publishAsEpub() {
RegistryHelper registry = new RegistryHelper(m_xContext);
try {
Object view = registry.getRegistryView(ToolbarSettingsDialog.REGISTRY_PATH, false);
XPropertySet xProps = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class,view);
short nEpubFormat = XPropertySetHelper.getPropertyValueAsShort(xProps, "EpubFormat");
switch (nEpubFormat) {
case 0: publish(TargetFormat.epub); break;
case 1: publish(TargetFormat.epub3);
}
} catch (Exception e) {
// Failed to get registry view
}
}
private void publish(TargetFormat format) {
if (unoPublisher==null) {
unoPublisher = new XhtmlUNOPublisher(m_xContext,m_xFrame,"Writer2xhtml");
}
unoPublisher.publish(format);
}
}

View file

@ -0,0 +1,220 @@
/************************************************************************
*
* XhtmlOptionsDialog.java
*
* Copyright: 2002-2014 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.4 (2014-09-25)
*
*/
package org.openoffice.da.comp.writer2xhtml;
import com.sun.star.awt.XDialog;
import com.sun.star.beans.XPropertySet;
import com.sun.star.uno.XComponentContext;
import org.openoffice.da.comp.w2lcommon.helper.PropertyHelper;
import org.openoffice.da.comp.w2lcommon.filter.OptionsDialogBase;
/** This class provides a uno component which implements a filter ui for the
* Xhtml export
*/
public class XhtmlOptionsDialog extends OptionsDialogBase {
/** The component will be registered under this name.
*/
public static String __serviceName = "org.openoffice.da.writer2xhtml.XhtmlOptionsDialog";
/** The component should also have an implementation name.
*/
public static String __implementationName = "org.openoffice.da.comp.writer2xhtml.XhtmlOptionsDialog";
public String getDialogLibraryName() { return "W2XDialogs"; }
/** Return the name of the dialog within the library
*/
public String getDialogName() { return "XhtmlOptions"; }
/** Return the name of the registry path
*/
public String getRegistryPath() {
return "/org.openoffice.da.Writer2xhtml.Options/XhtmlOptions";
}
/** Create a new XhtmlOptionsDialog */
public XhtmlOptionsDialog(XComponentContext xContext) {
super(xContext);
xMSF = W2XRegistration.xMultiServiceFactory;
}
/** Load settings from the registry to the dialog */
protected void loadSettings(XPropertySet xProps) {
// Style
loadConfig(xProps);
loadCheckBoxOption(xProps, "ConvertToPx");
int nScaling = loadNumericOption(xProps, "Scaling");
if (nScaling<=1) { // Workaround for an obscure bug in the extension manager
setNumericFieldValue("Scaling",100);
}
int nColumnScaling = loadNumericOption(xProps, "ColumnScaling");
if (nColumnScaling<=1) {
setNumericFieldValue("ColumnScaling",100);
}
loadCheckBoxOption(xProps, "OriginalImageSize");
// Special content
loadCheckBoxOption(xProps, "Notes");
loadCheckBoxOption(xProps, "UseDublinCore");
// AutoCorrect
loadCheckBoxOption(xProps, "IgnoreHardLineBreaks");
loadCheckBoxOption(xProps, "IgnoreEmptyParagraphs");
loadCheckBoxOption(xProps, "IgnoreDoubleSpaces");
// Files
loadCheckBoxOption(xProps, "Split");
loadListBoxOption(xProps, "SplitLevel");
loadListBoxOption(xProps, "RepeatLevels");
loadCheckBoxOption(xProps, "SaveImagesInSubdir");
loadCheckBoxOption(xProps, "UseMathjax");
updateLockedOptions();
enableControls();
}
/** Save settings from the dialog to the registry and create FilterData */
protected void saveSettings(XPropertySet xProps, PropertyHelper helper) {
// Style
short nConfig = saveConfig(xProps, helper);
String[] sCoreStyles = { "Chocolate", "Midnight", "Modernist",
"Oldstyle", "Steely", "Swiss", "Traditional", "Ultramarine" };
switch (nConfig) {
case 0: helper.put("ConfigURL","*default.xml"); break;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8: helper.put("ConfigURL","*cleanxhtml.xml");
helper.put("custom_stylesheet", "http://www.w3.org/StyleSheets/Core/"+sCoreStyles[nConfig-1]);
break;
case 9: helper.put("ConfigURL","$(user)/writer2xhtml.xml");
helper.put("AutoCreate","true");
helper.put("TemplateURL", "$(user)/writer2xhtml-template.xhtml");
helper.put("StyleSheetURL", "$(user)/writer2xhtml-styles.css");
}
saveCheckBoxOption(xProps, helper, "ConvertToPx", "convert_to_px");
saveNumericOptionAsPercentage(xProps, helper, "Scaling", "scaling");
saveNumericOptionAsPercentage(xProps, helper, "ColumnScaling", "column_scaling");
saveCheckBoxOption(xProps, "OriginalImageSize");
// TODO: Support "relative"
helper.put("image_size", getCheckBoxStateAsBoolean("OriginalImageSize") ? "none" : "absolute");
// Special content
saveCheckBoxOption(xProps, helper, "Notes", "notes");
saveCheckBoxOption(xProps, helper, "UseDublinCore", "use_dublin_core");
// AutoCorrect
saveCheckBoxOption(xProps, helper, "IgnoreHardLineBreaks", "ignore_hard_line_breaks");
saveCheckBoxOption(xProps, helper, "IgnoreEmptyParagraphs", "ignore_empty_paragraphs");
saveCheckBoxOption(xProps, helper, "IgnoreDoubleSpaces", "ignore_double_spaces");
// Files
boolean bSplit = saveCheckBoxOption(xProps, "Split");
short nSplitLevel = saveListBoxOption(xProps, "SplitLevel");
short nRepeatLevels = saveListBoxOption(xProps, "RepeatLevels");
if (!isLocked("split_level")) {
if (bSplit) {
helper.put("split_level",Integer.toString(nSplitLevel+1));
helper.put("repeat_levels",Integer.toString(nRepeatLevels));
}
else {
helper.put("split_level","0");
}
}
saveCheckBoxOption(xProps, helper, "SaveImagesInSubdir", "save_images_in_subdir");
saveCheckBoxOption(xProps, helper, "UseMathjax", "use_mathjax");
}
// Implement XDialogEventHandler
public boolean callHandlerMethod(XDialog xDialog, Object event, String sMethod) {
if (sMethod.equals("ConfigChange")) {
updateLockedOptions();
enableControls();
}
else if (sMethod.equals("SplitChange")) {
enableSplitLevel();
}
return true;
}
public String[] getSupportedMethodNames() {
String[] sNames = { "ConfigChange", "SplitChange" };
return sNames;
}
private void enableControls() {
// Style
setControlEnabled("ScalingLabel",!isLocked("scaling"));
setControlEnabled("Scaling",!isLocked("scaling"));
setControlEnabled("ColumnScalingLabel",!isLocked("column_scaling"));
setControlEnabled("ColumnScaling",!isLocked("column_scaling"));
setControlEnabled("ConvertToPx",!isLocked("convert_to_px"));
setControlEnabled("OriginalImageSize",!isLocked("image_size") && !isLocked("original_image_size"));
// Special content
setControlEnabled("Notes",!isLocked("notes"));
setControlEnabled("UseDublinCore",!isLocked("use_dublin_core"));
// AutoCorrect
setControlEnabled("IgnoreHardLineBreaks",!isLocked("ignore_hard_line_breaks"));
setControlEnabled("IgnoreEmptyParagraphs",!isLocked("ignore_empty_paragraphs"));
setControlEnabled("IgnoreDoubleSpaces",!isLocked("ignore_double_spaces"));
// Files
boolean bSplit = getCheckBoxStateAsBoolean("Split");
setControlEnabled("Split",!isLocked("split_level"));
setControlEnabled("SplitLevelLabel",!isLocked("split_level") && bSplit);
setControlEnabled("SplitLevel",!isLocked("split_level") && bSplit);
setControlEnabled("RepeatLevelsLabel",!isLocked("repeat_levels") && !isLocked("split_level") && bSplit);
setControlEnabled("RepeatLevels",!isLocked("repeat_levels") && !isLocked("split_level") && bSplit);
setControlEnabled("SaveImagesInSubdir",!isLocked("save_images_in_subdir"));
setControlEnabled("UseMathjax",(this instanceof XhtmlOptionsDialogMath) && !isLocked("use_mathjax"));
}
private void enableSplitLevel() {
if (!isLocked("split_level")) {
boolean bState = getCheckBoxStateAsBoolean("Split");
setControlEnabled("SplitLevelLabel",bState);
setControlEnabled("SplitLevel",bState);
if (!isLocked("repeat_levels")) {
setControlEnabled("RepeatLevelsLabel",bState);
setControlEnabled("RepeatLevels",bState);
}
}
}
}

View file

@ -0,0 +1,181 @@
/************************************************************************
*
* XhtmlOptionsDialogCalc.java
*
* Copyright: 2002-2014 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.4 (2014-09-25)
*
*/
package org.openoffice.da.comp.writer2xhtml;
import com.sun.star.awt.XDialog;
import com.sun.star.beans.XPropertySet;
import com.sun.star.uno.XComponentContext;
import org.openoffice.da.comp.w2lcommon.helper.PropertyHelper;
import org.openoffice.da.comp.w2lcommon.filter.OptionsDialogBase;
/** This class provides a uno component which implements a filter ui for the
* Xhtml export in Calc
*/
public class XhtmlOptionsDialogCalc extends OptionsDialogBase {
/** The component will be registered under this name.
*/
public static String __serviceName = "org.openoffice.da.writerxhtml.XhtmlOptionsDialogCalc";
/** The component should also have an implementation name.
*/
public static String __implementationName = "org.openoffice.da.comp.writer2xhtml.XhtmlOptionsDialogCalc";
public String getDialogLibraryName() { return "W2XDialogs"; }
/** Return the name of the dialog within the library
*/
public String getDialogName() { return "XhtmlOptionsCalc"; }
/** Return the name of the registry path
*/
public String getRegistryPath() {
return "/org.openoffice.da.Writer2xhtml.Options/XhtmlOptionsCalc";
}
/** Create a new XhtmlOptionsDialogCalc */
public XhtmlOptionsDialogCalc(XComponentContext xContext) {
super(xContext);
xMSF = W2XRegistration.xMultiServiceFactory;
}
/** Load settings from the registry to the dialog */
protected void loadSettings(XPropertySet xProps) {
// Style
loadConfig(xProps);
loadCheckBoxOption(xProps, "ConvertToPx");
int nScaling = loadNumericOption(xProps, "Scaling");
if (nScaling<=1) { // Workaround for an obscure bug in the extension manager
setNumericFieldValue("Scaling",100);
}
int nColumnScaling = loadNumericOption(xProps, "ColumnScaling");
if (nColumnScaling<=1) {
setNumericFieldValue("ColumnScaling",100);
}
loadCheckBoxOption(xProps, "OriginalImageSize");
// Special content
loadCheckBoxOption(xProps, "Notes");
loadCheckBoxOption(xProps, "UseDublinCore");
// Sheets
loadCheckBoxOption(xProps, "DisplayHiddenSheets");
loadCheckBoxOption(xProps, "DisplayHiddenRowsCols");
loadCheckBoxOption(xProps, "DisplayFilteredRowsCols");
loadCheckBoxOption(xProps, "ApplyPrintRanges");
loadCheckBoxOption(xProps, "UseTitleAsHeading");
loadCheckBoxOption(xProps, "UseSheetNamesAsHeadings");
// Files
loadCheckBoxOption(xProps, "CalcSplit");
loadCheckBoxOption(xProps, "SaveImagesInSubdir");
updateLockedOptions();
enableControls();
}
/** Save settings from the dialog to the registry and create FilterData */
protected void saveSettings(XPropertySet xProps, PropertyHelper helper) {
// Style
short nConfig = saveConfig(xProps, helper);
if (nConfig==0) {
helper.put("ConfigURL","*default.xml");
}
else if (nConfig==1) {
helper.put("ConfigURL","$(user)/writer2xhtml.xml");
helper.put("AutoCreate","true");
}
saveCheckBoxOption(xProps, helper, "ConvertToPx", "convert_to_px");
saveNumericOptionAsPercentage(xProps, helper, "Scaling", "scaling");
saveNumericOptionAsPercentage(xProps, helper, "ColumnScaling", "column_scaling");
saveCheckBoxOption(xProps, "OriginalImageSize");
// TODO: Support "relative"
helper.put("image_size", getCheckBoxStateAsBoolean("OriginalImageSize") ? "none" : "absolute");
// Special content
saveCheckBoxOption(xProps, helper, "Notes", "notes");
saveCheckBoxOption(xProps, helper, "UseDublinCore", "use_dublin_core");
// Sheets
saveCheckBoxOption(xProps, helper, "DisplayHiddenSheets", "display_hidden_sheets");
saveCheckBoxOption(xProps, helper, "DisplayHiddenRowsCols", "display_hidden_rows_cols");
saveCheckBoxOption(xProps, helper, "DisplayFilteredRowsCols", "display_filtered_rows_cols");
saveCheckBoxOption(xProps, helper, "ApplyPrintRanges", "apply_print_ranges");
saveCheckBoxOption(xProps, helper, "UseTitleAsHeading", "use_title_as_heading");
saveCheckBoxOption(xProps, helper, "UseSheetNamesAsHeadings", "use_sheet_names_as_headings");
// Files
saveCheckBoxOption(xProps, helper, "CalcSplit", "calc_split");
saveCheckBoxOption(xProps, helper, "SaveImagesInSubdir", "save_images_in_subdir");
}
// Implement XDialogEventHandler
public boolean callHandlerMethod(XDialog xDialog, Object event, String sMethod) {
if (sMethod.equals("ConfigChange")) {
updateLockedOptions();
enableControls();
}
return true;
}
public String[] getSupportedMethodNames() {
String[] sNames = { "ConfigChange" };
return sNames;
}
private void enableControls() {
// Style
setControlEnabled("ConvertToPx",!isLocked("convert_to_px"));
setControlEnabled("ScalingLabel",!isLocked("scaling"));
setControlEnabled("Scaling",!isLocked("scaling"));
setControlEnabled("ColumnScalingLabel",!isLocked("column_scaling"));
setControlEnabled("ColumnScaling",!isLocked("column_scaling"));
setControlEnabled("OriginalImageSize",!isLocked("image_size") && !isLocked("original_image_size"));
// Special content
setControlEnabled("Notes",!isLocked("notes"));
setControlEnabled("UseDublinCore",!isLocked("use_dublin_core"));
// Sheets
setControlEnabled("DisplayHiddenSheets", !isLocked("display_hidden_sheets"));
setControlEnabled("DisplayHiddenRowsCols", !isLocked("display_hidden_rows_cols"));
setControlEnabled("DisplayFilteredRowsCols", !isLocked("display_filtered_rows_cols"));
setControlEnabled("ApplyPrintRanges", !isLocked("apply_print_ranges"));
setControlEnabled("UseTitleAsHeading", !isLocked("use_title_as_heading"));
setControlEnabled("UseSheetNamesAsHeadings", !isLocked("use_sheet_names_as_headings"));
// Files
setControlEnabled("CalcSplit",!isLocked("calc_split"));
setControlEnabled("SaveImagesInSubdir",!isLocked("save_images_in_subdir"));
}
}

View file

@ -0,0 +1,48 @@
/************************************************************************
*
* XhtmlOptionsDialogMath.java
*
* Copyright: 2002-2004 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.4 (2014-08-18)
*
*/
package org.openoffice.da.comp.writer2xhtml;
import com.sun.star.uno.XComponentContext;
/** This class provides a uno component which implements a filter ui for the
* Xhtml export for the XHTML+MathML and HTML export.
* This variant of the dialog has the MathJax setting enabled
*/
public class XhtmlOptionsDialogMath extends XhtmlOptionsDialog {
/** The component will be registered under this name.
*/
public static String __serviceName = "org.openoffice.da.writer2xhtml.XhtmlOptionsDialogMath";
/** The component should also have an implementation name.
*/
public static String __implementationName = "org.openoffice.da.comp.writer2xhtml.XhtmlOptionsDialogMath";
/** Create a new XhtmlOptionsDialogMath */
public XhtmlOptionsDialogMath(XComponentContext xContext) {
super(xContext);
}
}

View file

@ -0,0 +1,146 @@
/************************************************************************
*
* XhtmlUNOPublisher.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-04-05)
*
*/
package org.openoffice.da.comp.writer2xhtml;
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.util.Vector;
import org.openoffice.da.comp.w2lcommon.filter.UNOPublisher;
import org.openoffice.da.comp.w2lcommon.helper.MessageBox;
import org.openoffice.da.comp.w2lcommon.helper.RegistryHelper;
import org.openoffice.da.comp.w2lcommon.helper.StreamGobbler;
import org.openoffice.da.comp.w2lcommon.helper.XPropertySetHelper;
import writer2latex.util.Misc;
import com.sun.star.beans.XPropertySet;
import com.sun.star.frame.XFrame;
import com.sun.star.uno.Exception;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
public class XhtmlUNOPublisher extends UNOPublisher {
public XhtmlUNOPublisher(XComponentContext xContext, XFrame xFrame, String sAppName) {
super(xContext, xFrame, sAppName);
}
/** Display the converted document depending on user settings
*
* @param sURL the URL of the converted document
* @param format the target format
*/
@Override protected void postProcess(String sURL, TargetFormat format) {
RegistryHelper registry = new RegistryHelper(xContext);
short nView = 1;
String sExecutable = null;
try {
Object view = registry.getRegistryView(ToolbarSettingsDialog.REGISTRY_PATH, false);
XPropertySet xProps = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class,view);
if (format==TargetFormat.xhtml || format==TargetFormat.xhtml11 || format==TargetFormat.xhtml_mathml || format==TargetFormat.html5) {
nView = XPropertySetHelper.getPropertyValueAsShort(xProps, "XhtmlView");
sExecutable = XPropertySetHelper.getPropertyValueAsString(xProps, "XhtmlExecutable");
}
else { // EPUB
nView = XPropertySetHelper.getPropertyValueAsShort(xProps, "EpubView");
sExecutable = XPropertySetHelper.getPropertyValueAsString(xProps, "EpubExecutable");
}
} catch (Exception e) {
// Failed to get registry view
}
File file = Misc.urlToFile(sURL);
if (file.exists()) {
if (nView==0) {
return;
}
else if (nView==1) {
if (openWithDefaultApplication(file)) {
return;
}
}
else if (nView==2) {
if (openWithCustomApplication(file, sExecutable)) {
return;
}
}
}
MessageBox msgBox = new MessageBox(xContext, xFrame);
msgBox.showMessage("Writer2xhtml","Error: Failed to open exported document");
}
// Open the file in the default application on this system (if any)
private boolean openWithDefaultApplication(File file) {
if (Desktop.isDesktopSupported()) {
Desktop desktop = Desktop.getDesktop();
try {
desktop.open(file);
return true;
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
return false;
}
// Open the file with the user defined application
private boolean openWithCustomApplication(File file, String sExecutable) {
try {
Vector<String> command = new Vector<String>();
command.add(sExecutable);
command.add(file.getPath());
ProcessBuilder pb = new ProcessBuilder(command);
Process proc = pb.start();
// Gobble the error stream of the application
StreamGobbler errorGobbler = new
StreamGobbler(proc.getErrorStream(), "ERROR");
// Gobble the output stream of the application
StreamGobbler outputGobbler = new
StreamGobbler(proc.getInputStream(), "OUTPUT");
errorGobbler.start();
outputGobbler.start();
// The application exists if the process exits with 0
return proc.waitFor()==0;
}
catch (InterruptedException e) {
return false;
}
catch (IOException e) {
return false;
}
}
}

View file

@ -0,0 +1,441 @@
/************************************************************************
*
* Application.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-01-09)
*
*/
package writer2latex;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
//import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Set;
import java.util.Vector;
import writer2latex.api.BatchConverter;
import writer2latex.api.Converter;
import writer2latex.api.ConverterFactory;
import writer2latex.api.ConverterResult;
import writer2latex.api.MIMETypes;
//import writer2latex.api.OutputFile;
import writer2latex.util.Misc;
/**
* <p>Command line utility to convert an OpenOffice.org Writer XML file into XHTML/LaTeX/BibTeX</p>
* <p>The utility is invoked with the following command line:</p>
* <pre>java -jar writer2latex.jar [options] source [target]</pre>
* <p>Where the available options are
* <ul>
* <li><code>-latex</code>, <code>-bibtex</code>, <code>-html5</code>, <code>-xhtml</code>,
<code>-xhtml+mathml</code>, <code>-epub</code>, <code>-epub3</code>
* <li><code>-recurse</code>
* <li><code>-ultraclean</code>, <code>-clean</code>, <code>-pdfscreen</code>,
* <code>-pdfprint</code>, <code>-cleanxhtml</code>
* <li><code>-config[=]filename</code>
* <li><code>-template[=]filename</code>
* <li><code>-stylesheet[=]filename</code>
* <li><code>-resource[=]filename[::media type]</code>
* <li><code>-option[=]value</code>
* </ul>
* <p>where <code>option</code> can be any simple option known to Writer2LaTeX
* (see documentation for the configuration file).</p>
*/
public final class Application {
/* Based on command-line parameters. */
private String sTargetMIME = MIMETypes.LATEX;
private boolean bRecurse = false;
private Vector<String> configFileNames = new Vector<String>();
private String sTemplateFileName = null;
private String sStyleSheetFileName = null;
private Set<String> resources = new HashSet<String>();
private Hashtable<String,String> options = new Hashtable<String,String>();
private String sSource = null;
private String sTarget = null;
/**
* Main method
*
* @param args The argument passed on the command line.
*/
public static final void main (String[] args){
try {
//long time = System.currentTimeMillis();
Application app = new Application();
app.parseCommandLine(args);
app.doConversion();
//System.out.println("Total conversion time was "+(System.currentTimeMillis()-time)+" miliseconds");
} catch (IllegalArgumentException ex) {
String msg = ex.getMessage();
showUsage(msg);
}
}
// Convert the directory or file
private void doConversion() {
// Step 1: Say hello...
String sOutputFormat;
if (MIMETypes.LATEX.equals(sTargetMIME)) { sOutputFormat = "LaTeX"; }
else if (MIMETypes.BIBTEX.equals(sTargetMIME)) { sOutputFormat = "BibTeX"; }
else { sOutputFormat = "xhtml"; }
System.out.println();
System.out.println("This is Writer2" + sOutputFormat +
", Version " + ConverterFactory.getVersion() +
" (" + ConverterFactory.getDate() + ")");
System.out.println();
System.out.println("Starting conversion...");
// Step 2: Examine source
File source = new File(sSource);
if (!source.exists()) {
System.out.println("I'm sorry, I can't find "+sSource);
System.exit(1);
}
if (!source.canRead()) {
System.out.println("I'm sorry, I can't read "+sSource);
System.exit(1);
}
boolean bBatch = source.isDirectory();
// Step 3: Examine target
File target;
if (bBatch) {
if (sTarget==null) {
target=source;
}
else {
target = new File(sTarget);
}
}
else {
if (sTarget==null) {
target = new File(source.getParent(),Misc.removeExtension(source.getName()));
}
else {
target = new File(sTarget);
if (sTarget.endsWith(File.separator)) {
target = new File(target,Misc.removeExtension(source.getName()));
}
}
}
// Step 4: Create converters
Converter converter = ConverterFactory.createConverter(sTargetMIME);
if (converter==null) {
System.out.println("Failed to create converter for "+sTargetMIME);
System.exit(1);
}
BatchConverter batchCv = null;
if (bBatch) {
batchCv = ConverterFactory.createBatchConverter(MIMETypes.XHTML);
if (batchCv==null) {
System.out.println("Failed to create batch converter");
System.exit(1);
}
batchCv.setConverter(converter);
}
// Step 5a: Read template
if (sTemplateFileName!=null) {
try {
System.out.println("Reading template "+sTemplateFileName);
byte [] templateBytes = Misc.inputStreamToByteArray(new FileInputStream(sTemplateFileName));
converter.readTemplate(new ByteArrayInputStream(templateBytes));
if (batchCv!=null) {
// Currently we use the same template for the directory and the files
batchCv.readTemplate(new ByteArrayInputStream(templateBytes));
}
}
catch (FileNotFoundException e) {
System.out.println("--> This file does not exist!");
System.out.println(" "+e.getMessage());
}
catch (IOException e) {
System.out.println("--> Failed to read the template file!");
System.out.println(" "+e.getMessage());
}
}
// Step 5b: Read style sheet
if (sStyleSheetFileName!=null) {
try {
System.out.println("Reading style sheet "+sStyleSheetFileName);
byte [] styleSheetBytes = Misc.inputStreamToByteArray(new FileInputStream(sStyleSheetFileName));
converter.readStyleSheet(new ByteArrayInputStream(styleSheetBytes));
}
catch (FileNotFoundException e) {
System.out.println("--> This file does not exist!");
System.out.println(" "+e.getMessage());
}
catch (IOException e) {
System.out.println("--> Failed to read the style sheet file!");
System.out.println(" "+e.getMessage());
}
}
// Step 5c: Read style resources
for (String sResource : resources) {
String sMediaType;
String sFileName;
int nSeparator = sResource.indexOf("::");
if (nSeparator>-1) {
sFileName = sResource.substring(0,nSeparator);
sMediaType = sResource.substring(nSeparator+2);
}
else {
sFileName = sResource;
sMediaType = null;
}
System.out.println("Reading resource file "+sFileName);
try {
byte [] resourceBytes = Misc.inputStreamToByteArray(new FileInputStream(sFileName));
converter.readResource(new ByteArrayInputStream(resourceBytes),sFileName,sMediaType);
} catch (IOException e) {
System.out.println("--> Failed to read the resource file!");
System.out.println(" "+e.getMessage());
}
}
// Step 6: Read config
for (int i=0; i<configFileNames.size(); i++) {
String sConfigFileName = (String) configFileNames.get(i);
if (sConfigFileName.startsWith("*")) {
sConfigFileName = sConfigFileName.substring(1);
System.out.println("Reading default configuration "+sConfigFileName);
try {
converter.getConfig().readDefaultConfig(sConfigFileName);
}
catch (IllegalArgumentException e) {
System.err.println("--> This configuration is unknown!");
System.out.println(" "+e.getMessage());
}
}
else {
System.out.println("Reading configuration file "+sConfigFileName);
try {
byte[] configBytes = Misc.inputStreamToByteArray(new FileInputStream(sConfigFileName));
converter.getConfig().read(new ByteArrayInputStream(configBytes));
if (bBatch) {
// Currently we use the same configuration for the directory and the files
batchCv.getConfig().read(new ByteArrayInputStream(configBytes));
}
}
catch (IOException e) {
System.err.println("--> Failed to read the configuration!");
System.out.println(" "+e.getMessage());
}
}
}
// Step 7: Set options from command line
Enumeration<String> keys = options.keys();
while (keys.hasMoreElements()) {
String sKey = keys.nextElement();
String sValue = (String) options.get(sKey);
converter.getConfig().setOption(sKey,sValue);
if (batchCv!=null) {
batchCv.getConfig().setOption(sKey,sValue);
}
}
// Step 8: Perform conversion
if (bBatch) {
batchCv.convert(source,target,bRecurse, new BatchHandlerImpl());
}
else {
System.out.println("Converting "+source.getPath());
ConverterResult dataOut = null;
try {
dataOut = converter.convert(source,target.getName());
}
catch (FileNotFoundException e) {
System.out.println("--> The file "+source.getPath()+" does not exist!");
System.out.println(" "+e.getMessage());
System.exit(1);
}
catch (IOException e) {
System.out.println("--> Failed to convert the file "+source.getPath()+"!");
System.out.println(" "+e.getMessage());
System.out.println(" Please make sure the file is in OpenDocument format");
System.exit(1);
}
// TODO: Should do some further checking on the feasability of writing
// the directory and the files.
File targetDir = target.getParentFile();
if (targetDir!=null && !targetDir.exists()) { targetDir.mkdirs(); }
try {
dataOut.write(targetDir);
}
catch (IOException e) {
System.out.println("--> Error writing out file!");
System.out.println(" "+e.getMessage());
System.exit(1);
}
}
// Step 9: Say goodbye!
System.out.println("Done!");
}
/**
* Display usage.
*/
private static void showUsage(String msg) {
System.out.println();
System.out.println("This is Writer2LaTeX, Version " + ConverterFactory.getVersion()
+ " (" + ConverterFactory.getDate() + ")");
System.out.println();
if (msg != null) System.out.println(msg);
System.out.println();
System.out.println("Usage:");
System.out.println(" java -jar <path>/writer2latex.jar <options> <source file/directory> [<target file/directory>]");
System.out.println("where the available options are:");
System.out.println(" -latex");
System.out.println(" -bibtex");
System.out.println(" -xhtml");
System.out.println(" -xhtml11");
System.out.println(" -xhtml+mathml");
System.out.println(" -html5");
System.out.println(" -epub");
System.out.println(" -epub3");
System.out.println(" -recurse");
System.out.println(" -template[=]<template file>");
System.out.println(" -stylesheet[=]<style sheet file>");
System.out.println(" -resource[=]<resource file>[::<media type>]");
System.out.println(" -ultraclean");
System.out.println(" -clean");
System.out.println(" -pdfprint");
System.out.println(" -pdfscreen");
System.out.println(" -cleanxhtml");
System.out.println(" -config[=]<configuration file>");
System.out.println(" -<configuration option>[=]<value>");
System.out.println("See the documentation for the available configuration options");
}
/**
* Parse command-line arguments.
*
* @param args Array of command line arguments.
*
* @throws IllegalArgumentException If an argument is invalid.
*/
private void parseCommandLine(String sArgs[])
throws IllegalArgumentException {
int i = 0;
while (i<sArgs.length) {
String sArg = getArg(i++,sArgs);
if (sArg.startsWith("-")) { // found an option
if ("-latex".equals(sArg)) { sTargetMIME = MIMETypes.LATEX; }
else if ("-bibtex".equals(sArg)) { sTargetMIME = MIMETypes.BIBTEX; }
else if ("-html5".equals(sArg)) { sTargetMIME = MIMETypes.HTML5; }
else if ("-xhtml".equals(sArg)) { sTargetMIME = MIMETypes.XHTML; }
else if ("-xhtml11".equals(sArg)) { sTargetMIME = MIMETypes.XHTML11; }
else if ("-xhtml+mathml".equals(sArg)) { sTargetMIME = MIMETypes.XHTML_MATHML; }
else if ("-epub".equals(sArg)) { sTargetMIME = MIMETypes.EPUB; }
else if ("-epub3".equals(sArg)) { sTargetMIME = MIMETypes.EPUB3; }
else if ("-recurse".equals(sArg)) { bRecurse = true; }
else if ("-ultraclean".equals(sArg)) { configFileNames.add("*ultraclean.xml"); }
else if ("-clean".equals(sArg)) { configFileNames.add("*clean.xml"); }
else if ("-pdfprint".equals(sArg)) { configFileNames.add("*pdfprint.xml"); }
else if ("-pdfscreen".equals(sArg)) { configFileNames.add("*pdfscreen.xml"); }
else if ("-cleanxhtml".equals(sArg)) { configFileNames.add("*cleanxhtml.xml"); }
else { // option with argument
int j=sArg.indexOf("=");
String sArg2;
if (j>-1) { // argument is separated by =
sArg2 = sArg.substring(j+1);
sArg = sArg.substring(0,j);
}
else { // argument is separated by space
sArg2 = getArg(i++,sArgs);
}
if ("-config".equals(sArg)) { configFileNames.add(sArg2); }
else if ("-template".equals(sArg)) { sTemplateFileName = sArg2; }
else if ("-stylesheet".equals(sArg)) { sStyleSheetFileName = sArg2; }
else if ("-resource".equals(sArg)) { resources.add(sArg2); }
else { // configuration option
options.put(sArg.substring(1),sArg2);
}
}
}
else { // not an option, so this must be the source
sSource = sArg;
// Possibly followed by the target
if (i<sArgs.length) {
String sArgument = getArg(i++,sArgs);
if (sArgument.length()>0) { sTarget = sArgument; }
}
// Skip any trailing empty arguments and signal an error if there's more
while (i<sArgs.length) {
String sArgument = getArg(i++,sArgs);
if (sArgument.length()>0) {
throw new IllegalArgumentException("I didn't expect "+sArgument+"?");
}
}
}
}
if (sSource==null) {
throw new IllegalArgumentException("Please specify a source document/directory!");
}
// Parsing of command line ended successfully!
}
/**
* Extract the next argument from the array, while checking to see
* that the array size is not exceeded. Throw a friendly error
* message in case the arg is missing.
*
* @param i Argument index.
* @param args Array of command line arguments.
*
* @return The argument with the specified index.
*
* @throws IllegalArgumentException If an argument is invalid.
*/
private String getArg(int i, String args[])
throws IllegalArgumentException {
if (i < args.length) {
return args[i];
}
else throw new
IllegalArgumentException("I'm sorry, the commandline ended abnormally");
}
}

View file

@ -0,0 +1,93 @@
/************************************************************************
*
* BatchHandlerImpl.java
*
* Copyright: 2002-2008 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.0 (2008-10-03)
*
*/
package writer2latex;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import writer2latex.api.BatchHandler;
/** This class implements a <code>BatchHandler</code> for command line usage
*/
public class BatchHandlerImpl implements BatchHandler {
private int nIndent = 0;
private void writeMessage(String sMsg) {
for (int i=0; i<nIndent; i++) {
System.out.print(" ");
}
System.out.println(sMsg);
}
public void startConversion() {
System.out.println("Press Enter to cancel the conversion");
}
public void endConversion() {
// No message
}
public void startDirectory(String sName) {
writeMessage("Converting directory "+sName);
nIndent++;
}
public void endDirectory(String sName, boolean bSuccess) {
nIndent--;
if (!bSuccess) {
writeMessage("--> Conversion of the directory "+sName+" failed!");
}
}
public void startFile(String sName) {
writeMessage("Converting file "+sName);
nIndent++;
}
public void endFile(String sName, boolean bSuccess) {
nIndent--;
if (!bSuccess) {
writeMessage("--> Conversion of the file "+sName+" failed!");
}
}
public boolean cancel() {
try {
if (System.in.available()>0) {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
in.readLine();
System.out.print("Do you want to cancel the conversion (y/n)? ");
String s = in.readLine();
if (s!= null && s.toLowerCase().startsWith("y")) { return true; }
}
}
catch (IOException e) {
}
return false;
}
}

View file

@ -0,0 +1,95 @@
/************************************************************************
*
* BatchConverter.java
*
* Copyright: 2002-2008 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.0 (2008-11-23)
*
*/
package writer2latex.api;
import java.io.File;
import java.io.InputStream;
import java.io.IOException;
/** This is an interface for a converter, which offers conversion of
* all OpenDocument (or OpenOffice.org 1.x) documents in a directory
* (and optionally subdirectories), creating index pages in a specific format.
* Instances of this interface are created using the
* {@link ConverterFactory}
*/
public interface BatchConverter {
/** Get the configuration interface for this batch converter
*
* @return the configuration
*/
public Config getConfig();
/** Define a <code>Converter</code> implementation to use for
* conversion of the individual documents.
* If no converter is given, the <code>convert</code> method cannot
* convert documents (but can still create index pages).
*
* @param converter the <code>Converter</code> to use
*/
public void setConverter(Converter converter);
/** Read a template to use as a base for the index pages.
* The format of the template depends on the <code>BatchConverter</code>
* implementation.
*
* @param is an <code>InputStream</code> from which to read the template
* @throws IOException if some exception occurs while reading the template
*/
public void readTemplate(InputStream is) throws IOException;
/** Read a template to use as a base for the index pages.
* The format of the template depends on the <code>BatchConverter</code>
* implementation.
*
* @param file the file from which to read the template
* @throws IOException if the file does not exist or some exception occurs
* while reading the template
*/
public void readTemplate(File file) throws IOException;
/** Create an index page with specific entries
*
* @param sHeading a heading describing the index page
* @param entries an array of <code>IndexPageEntry</code> objects (null entries
* are allowed, and will be ignored) describing the individual directories
* and documents
*/
public OutputFile createIndexFile(String sHeading, IndexPageEntry[] entries);
/** Convert a directory using the given <code>Converter</code> (if none is given,
* all files will be ignored).
* This method fails silently if you haven't set a converter.
*
* @param source a <code>File</code> representing the directory to convert
* @param target a <code>File</code> representing the directory to contain
* the converted documents
* @param bRecurse determines wether or not to recurse into subdirectories
* @param handler a </code>BatchHandler</code>
*/
public void convert(File source, File target, boolean bRecurse, BatchHandler handler);
}

View file

@ -0,0 +1,76 @@
/************************************************************************
*
* BatchHandler.java
*
* Copyright: 2002-2008 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.0 (2008-11-23)
*
*/
package writer2latex.api;
/** This is a call back interface to handle user interaction during a
* batch conversion with a {@link BatchConverter}
*/
public interface BatchHandler {
/** Notification that the conversion is started */
public void startConversion();
/** Notification that the conversion has finished */
public void endConversion();
/** Notification that a directory conversion starts
*
* @param sName the name of the directory to convert
*/
public void startDirectory(String sName);
/** Notification that a directory conversion has finished
*
* @param sName the name of the directory
* @param bSuccess true if the conversion was successful (this only means
* that the index page was created with success, not that the conversion
* of files and subdirectories was successful)
*/
public void endDirectory(String sName, boolean bSuccess);
/** Notification that a file conversion starts
*
* @param sName the name of the file to convert
*/
public void startFile(String sName);
/** Notification that a file conversion has finished
*
* @param sName the name of the file
* @param bSuccess true if the conversion of this file was successful
*/
public void endFile(String sName, boolean bSuccess);
/** Notification that the conversion may be cancelled. The
* {@link BatchConverter} fires this event once per document.
* Cancelling the conversion does not delete files that was already
* converted
*
* @return true if the handler wants to cancel the conversion
*/
public boolean cancel();
}

View file

@ -0,0 +1,120 @@
/************************************************************************
*
* Config.java
*
* Copyright: 2002-2009 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.2 (2009-11-19)
*
*/
package writer2latex.api;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/** A complex option is a set of named keys, each pointing to a set of named attributes
*/
public class ComplexOption {
private Map<String,Map<String,String>> options = new HashMap<String,Map<String,String>>();
/** Clear the contents of the set
*
*/
public void clear() {
options.clear();
}
/** Remove an option from the set, if it exists
*
* @param sName the name of the key to remove
*/
public void remove(String sName) {
if (options.containsKey(sName)) {
options.remove(sName);
}
}
/** Define a key. If the key already exists, the old value will be replaced
*
* @param sName the name of the key. The name must be non-empty, otherwise the request will be ignored.
* @param attributes
*/
public void put(String sName, Map<String,String> attributes) {
if (sName!=null && sName.length()>0) {
options.put(sName, attributes);
}
}
/** Define a key using a <i>copy</i> of a the provided attributes.
* If the key already exists, the old value will be replaced
*
* @param sName the name of the key. The name must be non-empty, otherwise the request will be ignored.
* @param attributes
*/
public void copy(String sName, Map<String,String> attributes) {
if (sName!=null && sName.length()>0) {
Map<String,String> newAttributes = new HashMap<String,String>();
for (String sAttrName : attributes.keySet()) {
newAttributes.put(sAttrName, attributes.get(sAttrName));
}
put(sName, newAttributes);
}
}
/** Get the value belonging to a key
*
* @param sName the name of the key
* @return the attributes, or null if the option doesn't exist
*/
public Map<String,String> get(String sName) {
return options.get(sName);
}
/** Copy all values from another <code>ComplexOption</code>
* (overwrites existing values)
* @param co another instance of <code>ComplexOption</code>
*/
public void copyAll(ComplexOption co) {
for (String sName : co.keySet()) {
copy(sName, co.get(sName));
}
}
/** Get the names of all options that are currently defined by this complex option
*
* @return all names as a <code>Set</code>
*/
public Set<String> keySet() {
return options.keySet();
}
/** Test if this complex options contains a specific option name
*
* @param sName the name to test
* @return true if the name exists
*/
public boolean containsKey(String sName) {
return options.containsKey(sName);
}
}

View file

@ -0,0 +1,105 @@
/************************************************************************
*
* Config.java
*
* Copyright: 2002-2009 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.2 (2009-09-22)
*
*/
package writer2latex.api;
import java.io.File;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.IllegalArgumentException;
/** This is an interface for configuration of a {@link Converter}.
* A configuration always supports simple name/value options.
* In addition, you can read and write configurations using streams
* or abstract file names. The format depends on the {@link Converter}
* implementation, cf. the user's manual.
*/
public interface Config {
/** Read a default configuration: The available configurations depend on the
* {@link Converter} implementation
*
* @param sName the name of the configuration
* @throws IllegalArgumentException if the configuration does not exist
*/
public void readDefaultConfig(String sName) throws IllegalArgumentException;
/** Read a configuration (stream based version)
*
* @param is the <code>InputStream</code> to read from
* @throws IOException if an error occurs reading the stream, or the data
* is not in the right format
*/
public void read(InputStream is) throws IOException;
/** Read a configuration (file based version)
*
* @param file the <code>File</code> to read from
* @throws IOException if the file does not exist, an error occurs reading
* the file, or the data is not in the right format
*/
public void read(File file) throws IOException;
/** Write the configuration (stream based version)
*
* @param os the <code>OutputStream</code> to write to
* @throws IOException if an error occurs writing to the stream
*/
public void write(OutputStream os) throws IOException;
/** Write the configuration (file based version)
*
* @param file the <code>File</code> to write to
* @throws IOException if an error occurs writing to the file
*/
public void write(File file) throws IOException;
/** Set a name/value option. Options that are not defined by the
* {@link Converter} implementation as well as null values are
* silently ignored
*
* @param sName the name of the option
* @param sValue the value of the option
*/
public void setOption(String sName, String sValue);
/** Get a named option
*
* @param sName the name of the option
* @return the value of the option, or <code>null</code> if the option does
* not exist or the given name is null
*/
public String getOption(String sName);
/** Get a complex option
*
* @param sName the name of the complex option
* @return the option
*/
public ComplexOption getComplexOption(String sName);
}

View file

@ -0,0 +1,60 @@
/************************************************************************
*
* ContentEntry.java
*
* Copyright: 2002-2010 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.2 (2010-03-15)
*
*/
package writer2latex.api;
/** This interface represents a content entry, that is a named reference
* to a position within the output document.
*/
public interface ContentEntry {
/** Get the outline level of this <code>ContentEntry</code>.
* The top level is 1 (entries corresponding to indexes are considered
* top level).
* Note that intermediate levels may be missing (e.g. a heading of
* level 3 may follow immediately after a heading of level 1).
*
* @return the outline level
*/
public int getLevel();
/** Get the title for this entry
*
* @return the title
*/
public String getTitle();
/** Get the file associated with the entry
*
* @return the output file
*/
public OutputFile getFile();
/** Get the name of a target within the file, if any
*
* @return the target name, or null if no target is needed
*/
public String getTarget();
}

View file

@ -0,0 +1,153 @@
/************************************************************************
*
* Converter.java
*
* Copyright: 2002-2014 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.4 (2014-08-28)
*
*/
package writer2latex.api;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.IOException;
/** This is an interface for a converter, which offers conversion of
* OpenDocument (or OpenOffice.org 1.x) documents into a specific format.
* Instances of this interface are created using the
* <code>ConverterFactory</code>
*/
public interface Converter {
/** Get the interface for the configuration of this converter
*
* @return the configuration
*/
public Config getConfig();
/** Define a <code>GraphicConverter</code> implementation to use for
* conversion of graphic files. If no converter is specified, graphic
* files will not be converted into other formats.
*
* @param gc the <code>GraphicConverter</code> to use
*/
public void setGraphicConverter(GraphicConverter gc);
/** Read a template to use as a base for the converted document.
* The format of the template depends on the <code>Converter</code>
* implementation.
*
* @param is an <code>InputStream</code> from which to read the template
* @throws IOException if some exception occurs while reading the template
*/
public void readTemplate(InputStream is) throws IOException;
/** Read a template to use as a base for the converted document.
* The format of the template depends on the <code>Converter</code>
* implementation.
*
* @param file a file from which to read the template
* @throws IOException if the file does not exist or some exception occurs
* while reading the template
*/
public void readTemplate(File file) throws IOException;
/** Read a style sheet to <em>include</em> with the converted document.
* The format of the style sheet depends on the <code>Converter</code>
* implementation.
*
* @param is an <code>InputStream</code> from which to read the style sheet
* @throws IOException if some exception occurs while reading the style sheet
*/
public void readStyleSheet(InputStream is) throws IOException;
/** Read a style sheet to <em>include</em> with the converted document.
* The format of the style sheet depends on the <code>Converter</code>
* implementation.
*
* @param file a file from which to read the style sheet
* @throws IOException if the file does not exist or some exception occurs
* while reading the style sheet
*/
public void readStyleSheet(File file) throws IOException;
/** Read a resource to <em>include</em> with the converted document.
* A resource can be any (binary) file and will be placed in the same directory as
* the style sheet
*
* @param is an <code>InputStream</code> from which to read the resource
* @param sFileName the file name to use for the resource
* @param sMediaType the media type of the resource, if null the media type will be guessed from the file name
* @throws IOException if some exception occurs while reading the resource
*/
public void readResource(InputStream is, String sFileName, String sMediaType) throws IOException;
/** Read a style sheet to <em>include</em> with the converted document.
* A resource can be any (binary) file and will be placed in the same directory as
* the style sheet
*
* @param file a file from which to read the style sheet
* @param sFileName the file name to use for the resource
* @param sMediaType the media type of the resource, if null the media type will be guessed from the file name
* @throws IOException if the file does not exist or some exception occurs
* while reading the resource
*/
public void readResource(File file, String sFileName, String sMediaType) throws IOException;
/** Convert a document
*
* @param is an <code>InputStream</code> from which to read the source document.
* @param sTargetFileName the file name to use for the converted document
* (if the converted document is a compound document consisting consisting
* of several files, this name will be used for the master document)
* @return a <code>ConverterResult</code> containing the converted document
* @throws IOException if some exception occurs while reading the document
*/
public ConverterResult convert(InputStream is, String sTargetFileName)
throws IOException;
/** Convert a document
*
* @param source a <code>File</code> from which to read the source document.
* @param sTargetFileName the file name to use for the converted document
* (if the converted document is a compound document consisting consisting
* of several files, this name will be used for the master document)
* @return a <code>ConverterResult</code> containing the converted document
* @throws FileNotFoundException if the file does not exist
* @throws IOException if some exception occurs while reading the document
*/
public ConverterResult convert(File source, String sTargetFileName)
throws FileNotFoundException, IOException;
/** Convert a document
*
* @param dom a DOM tree representing the document as flat XML
* @param sTargetFileName the file name to use for the converted document
* (if the converted document is a compound document consisting consisting
* of several files, this name will be used for the master document)
* @param bDestructive set to true if the converter is allowed to remove contents from the DOM tree (to save memory)
* @return a <code>ConverterResult</code> containing the converted document
* @throws IOException if some exception occurs while reading the document
*/
public ConverterResult convert(org.w3c.dom.Document dom, String sTargetFileName, boolean bDestructive)
throws IOException;
}

View file

@ -0,0 +1,143 @@
/************************************************************************
*
* ConverterFactory.java
*
* Copyright: 2002-2018 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 2.0 (2018-03-06)
*
*/
package writer2latex.api;
/** This is a factory class which provides static methods to create converters
* for documents in OpenDocument (or OpenOffice.org 1.x) format into a specific MIME type
*/
public class ConverterFactory {
// Version information
private static final String VERSION = "1.9.1";
private static final String DATE = "2018-03-06";
/** Return the Writer2LaTeX version in the form
* (major version).(minor version).(patch level)<br/>
* Development versions have an odd minor version number
* @return the version number
*/
public static String getVersion() { return VERSION; }
/** Return date information
* @return the release date for this Writer2LaTeX version
*/
public static String getDate() { return DATE; }
/** <p>Create a <code>Converter</code> implementation which supports
* conversion into the specified MIME type.</p>
* <p>Currently supported MIME types are:</p>
* <ul>
* <li><code>application/x-latex</code> for LaTeX format</li>
* <li><code>application/x-bibtex</code> for BibTeX format</li>
* <li><code>text/html</code> for XHTML 1.0 strict format</li>
* <li><code>application/xhtml11</code> for XHTML 1.1 format
* Note that this is <em>not</em> the recommended media type for XHTML 1.1
* (see http://www.w3.org/TR/xhtml-media-types/), but it is used internally
* by Writer2xhtml to distinguish from XHTML+MathML</li>
* <li><code>application/xhtml+xml</code> for XHTML+MathML</li>
* <li><code>text/html5</code> for HTML5 documents
* Note that this is <em>not</em> the recommended media type for HTML5
* (see http://wiki.whatwg.org/), but it is used internally
* by Writer2xhtml to distinguish from HTML5</li>
* <li><code>application/epub+zip</code></li> for EPUB format</li>
* <li><code>epub3</code> for EPUB 3 format</li>
* </ul>
*
* @param sMIME the MIME type of the target format
* @return the required <code>Converter</code> or null if a converter for
* the requested MIME type could not be created
*/
public static Converter createConverter(String sMIME) {
Object converter = null;
if (MIMETypes.LATEX.equals(sMIME)) {
converter = createInstance("writer2latex.latex.ConverterPalette");
}
else if (MIMETypes.BIBTEX.equals(sMIME)) {
converter = createInstance("writer2latex.bibtex.Converter");
}
else if (MIMETypes.XHTML.equals(sMIME)) {
converter = createInstance("writer2latex.xhtml.Xhtml10Converter");
}
else if (MIMETypes.XHTML11.equals(sMIME)) {
converter = createInstance("writer2latex.xhtml.Xhtml11Converter");
}
else if (MIMETypes.XHTML_MATHML.equals(sMIME)) {
converter = createInstance("writer2latex.xhtml.XhtmlMathMLConverter");
}
else if (MIMETypes.HTML5.equals(sMIME)) {
converter = createInstance("writer2latex.xhtml.Html5Converter");
}
else if (MIMETypes.EPUB3.equals(sMIME)) {
converter = createInstance("writer2latex.epub.EPUB3Converter");
}
else if (MIMETypes.EPUB.equals(sMIME)) {
converter = createInstance("writer2latex.epub.EPUBConverter");
}
return converter instanceof Converter ? (Converter) converter : null;
}
/** <p>Create a <code>BatchConverter</code> implementation which supports
* conversion into the specified MIME type</p>
* <p>The only currently supported MIME type is <code>text/html</code>
* (XHTML 1.0 strict)</p>
*
* @param sMIME the MIME type of the target format
* @return the required <code>BatchConverter</code> or null if a converter
* for the requested MIME type could not be created
*/
public static BatchConverter createBatchConverter(String sMIME) {
Object converter = null;
if (MIMETypes.XHTML.equals(sMIME)) {
converter = createInstance("writer2latex.xhtml.BatchConverterImpl");
}
return converter instanceof BatchConverter ? (BatchConverter) converter : null;
}
/** Create a <code>StarMathConverter</code> implementation
*
* @return the converter
*/
public static StarMathConverter createStarMathConverter() {
Object converter = createInstance("writer2latex.latex.StarMathConverter");
return converter instanceof StarMathConverter ? (StarMathConverter) converter : null;
}
private static Object createInstance(String sClassName) {
try {
return Class.forName(sClassName).newInstance();
}
catch (java.lang.ClassNotFoundException e) {
return null;
}
catch (java.lang.InstantiationException e) {
return null;
}
catch (java.lang.IllegalAccessException e) {
return null;
}
}
}

View file

@ -0,0 +1,131 @@
/************************************************************************
*
* ConverterResult.java
*
* Copyright: 2002-2011 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.2 (2011-07-20)
*
*/
package writer2latex.api;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
/** A <code>ConverterResult</code> represent a document, which is the result
* of a conversion performed by a <code>Converter</code>implementation.
*/
public interface ConverterResult {
/** Get the master document
* Deprecated as of Writer2LaTeX 1.2: The master document is always the first document
* returned by the <code>iterator</code>
*
* @return <code>OutputFile</code> the master document
*/
@Deprecated public OutputFile getMasterDocument();
/** Gets an <code>Iterator</code> to access all files in the
* <code>ConverterResult</code>. The iterator will return the master documents first
* in logical order (starting with the primary master document)
* @return an <code>Iterator</code> of all files
*/
public Iterator<OutputFile> iterator();
/** Get the meta data associated with the source document
* @return the meta data
*/
public MetaData getMetaData();
/** Get the content table (based on headings) for this <code>ConverterResult</code>
*
* @return list view of the content
*/
public List<ContentEntry> getContent();
/** Get the entry which contains the table page
*
* @return the entry or null if there is no title page
*/
public ContentEntry getTitlePageFile();
/** Get the entry which contains the start of the actual text (the first chapter, or simply the start of
* the document if there are no headings)
*
* @return the entry
*/
public ContentEntry getTextFile();
/** Get the entry which contains the table of contents
*
* @return the entry or null if a table of content does not exist
*/
public ContentEntry getTocFile();
/** Get the entry which contains the list of tables
*
* @return the entry or null if a list of tables does not exist
*/
public ContentEntry getLotFile();
/** Get the entry which contains the list of figures
*
* @return the entry or null if a list of figures does not exist
*/
public ContentEntry getLofFile();
/** Get the entry which contains the alphabetical index
*
* @return the entry or null if an alphabetical index does not exist
*/
public ContentEntry getIndexFile();
/** Get the entry which contains the bibliography
*
* @return the entry or null if a bibliography does not exist
*/
public ContentEntry getBibliographyFile();
/** Get the entry which contains the cover (which usually will contain a cover image)
*
* @return the entry or null if a cover does not exist
*/
public ContentEntry getCoverFile();
/** Get the entry which contains the actual cover image
*
* @return the entry or null if a cover image does not exist
*/
public ContentEntry getCoverImageFile();
/** Write all files of the <code>ConverterResult</code> to a directory.
* Subdirectories are created as required by the individual
* <code>OutputFile</code>s.
* @param dir the directory to write to (this directory must exist).
If the parameter is null, the default directory is used
* @throws IOException if the directory does not exist or one or more files
* could not be written
*/
public void write(File dir) throws IOException;
}

View file

@ -0,0 +1,57 @@
/************************************************************************
*
* GraphicConverter.java
*
* Copyright: 2002-2008 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.0 (2008-11-23)
*
*/
package writer2latex.api;
/** A simple interface for a graphic converter which converts between various
* graphics formats
*/
public interface GraphicConverter {
/** Check whether a certain conversion is supported by the converter
*
* @param sSourceMime a string containing the source Mime type
* @param sTargetMime a string containing the target Mime type
* @param bCrop true if the target graphic should be cropped
* @param bResize true if the target graphic should be resized
* (the last two parameters are for future use)
* @return true if the conversion is supported
*/
public boolean supportsConversion(String sSourceMime, String sTargetMime, boolean bCrop, boolean bResize);
/** Convert a graphics file from one format to another
*
* @param source a byte array containing the source graphic
* @param sSourceMime a string containing the Mime type of the source
* @param sTargetMime a string containing the desired Mime type of the target
* @return a byte array containing the converted graphic. Returns null
* if the conversion failed.
*/
public byte[] convert(byte[] source, String sSourceMime, String sTargetMime);
}

View file

@ -0,0 +1,140 @@
/************************************************************************
*
* IndexPageEntry.java
*
* Copyright: 2002-2009 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.0 (2009-02-08)
*
*/
package writer2latex.api;
/** This class represents a single entry on an index page created by a batch converter
*/
public class IndexPageEntry {
private String sFile;
private String sDisplayName;
private String sDescription = null;
private String sPdfFile = null;
private String sOriginalFile = null;
private boolean bIsDirectory;
/** Construct a new <code>IndexPageEntry</code> based on a file name.
* The file name is also used as display name.
*
* @param sFile the file name for this entry
* @param bIsDirectory true if this is a directory, false if it is a file
*/
public IndexPageEntry(String sFile, boolean bIsDirectory) {
this.sFile = sFile;
this.sDisplayName = sFile;
this.bIsDirectory = bIsDirectory;
}
/** Set the file name
*
* @param sFile the file name
*/
public void setFile(String sFile) {
this.sFile = sFile;
}
/** Set the display name for this entry. The display name is the
* name presented on the index page.
*
* @param sDisplayName the display name
*/
public void setDisplayName(String sDisplayName) {
this.sDisplayName = sDisplayName;
}
/** Set the description of this file (additional information about the file)
*
* @param sDescription the description
*/
public void setDescription(String sDescription) {
this.sDescription = sDescription;
}
/** Set the file name for a pdf file associated with this file
*
* @param sPdfFile the file name
*/
public void setPdfFile(String sPdfFile) {
this.sPdfFile = sPdfFile;
}
/** Set the file name for the original file
*
* @param sOriginalFile the origianl file name
*/
public void setOriginalFile(String sOriginalFile) {
this.sOriginalFile = sOriginalFile;
}
/** Get the file name
*
* @return the file name
*/
public String getFile() {
return sFile;
}
/** Get the display name
*
* @return the display name
*/
public String getDisplayName() {
return sDisplayName;
}
/** Get the description
*
* @return the description, or null if there is no description
*/
public String getDescription() {
return sDescription;
}
/** Get the pdf file name
*
* @return the file name or null if there is none
*/
public String getPdfFile() {
return sPdfFile;
}
/** Get the original file name
*
* @return the file name or null if there is none
*/
public String getOriginalFile() {
return sOriginalFile;
}
/** Check whether this is a file or a directory
*
* @return true for a directory, false for a file
*/
public boolean isDirectory() {
return bIsDirectory;
}
}

View file

@ -0,0 +1,62 @@
/************************************************************************
*
* MIMETypes.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-01-09)
*
*/
package writer2latex.api;
/* Some helpers to handle the MIME types used by OOo and Writer2LaTeX
*/
public class MIMETypes {
// Various graphics formats, see
// http://api.openoffice.org/docs/common/ref/com/sun/star/graphic/MediaProperties.html#MimeType
public static final String PNG="image/png";
public static final String JPEG="image/jpeg";
public static final String GIF="image/gif";
public static final String TIFF="image/tiff";
public static final String BMP="image/bmp";
public static final String EMF="image/x-emf";
public static final String WMF="image/x-wmf";
public static final String EPS="image/x-eps";
public static final String SVG="image/svg+xml";
// MIME type for SVM has changed
//public static final String SVM="image/x-svm";
public static final String SVM="application/x-openoffice-gdimetafile;windows_formatname=\"GDIMetaFile\"";
public static final String PDF="application/pdf";
// Destination formats
public static final String XHTML="text/html";
/** This is a fake MIME type, for internal use only */
public static final String XHTML11="application/xhtml11";
public static final String XHTML_MATHML="application/xhtml+xml";
/** This is a fake MIME type, for internal use only */
public static final String HTML5="text/html5";
public static final String EPUB="application/epub+zip";
/** This is not a MIME type either */
public static final String EPUB3="epub3";
public static final String LATEX="application/x-latex";
public static final String BIBTEX="application/x-bibtex";
public static final String TEXT="text";
}

View file

@ -0,0 +1,81 @@
/************************************************************************
*
* MetaData.java
*
* Copyright: 2002-2010 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.2 (2010-12-15)
*
*/
package writer2latex.api;
import java.util.Map;
/** This interface provides access to the predefined meta data of the
* source document (currently incomplete)
*/
public interface MetaData {
/** Get the title of the source document
*
* @return the title (may return an empty string)
*/
public String getTitle();
/** Get the subject of the source document
*
* @return the subject (may return an empty string)
*/
public String getSubject();
/** Get the keywords of the source document
*
* @return the keywords as a comma separated list (may return an empty string)
*/
public String getKeywords();
/** Get the description of the source document
*
* @return the description (may return an empty string)
*/
public String getDescription();
/** Get the creator of the source document (or the initial creator if none is specified)
*
* @return the creator (may return an empty string)
*/
public String getCreator();
/** Get the (main) language of the document
*
* @return the language
*/
public String getLanguage();
/** Get the date of the source document
*
* @return the date (may return an empty string)
*/
public String getDate();
/** Get the user-defined meta data
*
* @return the user-defined meta data as a name-value map
*/
public Map<String,String> getUserDefinedMetaData();
}

View file

@ -0,0 +1,70 @@
/************************************************************************
*
* OutputFile.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-05-05)
*
*/
package writer2latex.api;
import java.io.OutputStream;
import java.io.IOException;
/** An <code>OutputFile</code> represents a single file in a
* {@link ConverterResult}, which is output from a {@link Converter}
* implementation.
*/
public interface OutputFile {
/** Writes the <code>OutputFile</code> to an <code>OutputStream</code>.
*
* @param os <code>OutputStream</code> to which the content should be written
* @throws IOException if any I/O error occurs
*/
public void write(OutputStream os) throws IOException;
/** Returns the file name of the <code>OutputFile</code>. This includes
* the file extension and may also include a relative path, always using
* / as separator.
*
* @return the file name of this <code>OutputFile</code>
*/
public String getFileName();
/** Get the MIME type of the <code>OutputFile</code>.
*
* @return string representation of the MIME type
*/
public String getMIMEType();
/** Test whether this document is part of the main document flow (master documents) or
* an auxiliary document
*
* @return true if this document is a master document
*/
public boolean isMasterDocument();
/** Test whether this document contains mathematical formulas
*
* @return true if the document contains formulas
*/
public boolean containsMath();
}

View file

@ -0,0 +1,13 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>The package writer2latex.api</title>
</head>
<body>
<p>This package contains the api for using Writer2LaTeX.</p>
<p>The api consitst of a factory class and a number of interfaces, and is
used by the command line application as well as by the filters.
</body>
</html>

View file

@ -0,0 +1,60 @@
/************************************************************************
*
* StarMathConverter.java
*
* Copyright: 2002-2008 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.0 (2008-11-23)
*
*/
package writer2latex.api;
//import java.io.InputStream;
//import java.io.IOException;
/** This is an interface for a converter, which offers conversion of
* a StarMath formula into LaTeX
* Instances of this interface are created using the
* {@link ConverterFactory}
*/
public interface StarMathConverter {
/** Get the configuration used when converting.
*
* @return the configuration used by this converter
*/
public Config getConfig();
/** Convert a StarMath formula
*
* @param sStarMathFormula is a string containing the StarMath formula
* @return a string containing the converted LaTeX formula
*/
public String convert(String sStarMathFormula);
/** Create a suitable LaTeX preamble to process the formulas converted so far
*
* @return a string containg the entire LaTeX preamble
*/
public String getPreamble();
}

View file

@ -0,0 +1,181 @@
/************************************************************************
*
* BatchConverterBase.java
*
* Copyright: 2002-2014 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.4 (2014-08-27)
*
*/
package writer2latex.base;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import writer2latex.api.BatchConverter;
import writer2latex.api.BatchHandler;
import writer2latex.api.Converter;
import writer2latex.api.ConverterResult;
import writer2latex.api.IndexPageEntry;
import writer2latex.api.OutputFile;
import writer2latex.util.Misc;
/**
* Abstract base implementation of <code>writer2latex.api.BatchConverter</code>.
* The base implementation handles the traversal of directories and files, and
* leaves the handling of indexpages to the subclass.
*/
public abstract class BatchConverterBase implements BatchConverter {
private Converter converter;
public BatchConverterBase() {
converter = null;
}
// Partial implementation of the interface
public void setConverter(Converter converter) {
this.converter = converter;
}
public void convert(File source, File target, boolean bRecurse, BatchHandler handler) {
handler.startConversion();
convertDirectory(source, target, bRecurse, source.getName(), handler);
handler.endConversion();
}
protected abstract String getIndexFileName();
// Convert files and directories in the directory indir
// (return false if conversion has been cancelled by the BatchHandler)
private boolean convertDirectory(File indir, File outdir, boolean bRecurse, String sHeading, BatchHandler handler) {
handler.startDirectory(indir.getPath());
// Step 1: Get the directory
File[] contents = indir.listFiles();
int nLen = contents.length;
IndexPageEntry[] entries = new IndexPageEntry[nLen];
// Step 2: Traverse subdirectories, if allowed
if (bRecurse) {
String sUplink = getConfig().getOption("uplink");
for (int i=0; i<nLen; i++) {
if (contents[i].isDirectory()) {
getConfig().setOption("uplink","../"+getIndexFileName());
File newOutdir = new File(outdir,contents[i].getName());
String sNewHeading = sHeading + " - " + contents[i].getName();
boolean bResult = convertDirectory(contents[i],newOutdir,bRecurse,sNewHeading,handler);
getConfig().setOption("uplink", sUplink);
if (!bResult) { return false; }
// Create entry for this subdirectory
IndexPageEntry entry = new IndexPageEntry(Misc.makeHref(contents[i].getName()+"/"+getIndexFileName()),true);
entry.setDisplayName(contents[i].getName());
entries[i]=entry;
}
}
}
// Step 3: Traverse documents, if we have a converter
if (converter!=null) {
String sUplink = getConfig().getOption("uplink");
for (int i=0; i<nLen; i++) {
if (contents[i].isFile()) {
getConfig().setOption("uplink",getIndexFileName());
String sLinkFile = convertFile(contents[i],outdir,handler);
getConfig().setOption("uplink", sUplink);
if (sLinkFile!=null) {
// Create entry for this file
IndexPageEntry entry = new IndexPageEntry(Misc.makeHref(sLinkFile),false);
entry.setDisplayName(Misc.removeExtension(sLinkFile));
entries[i]=entry;
if (handler.cancel()) { return false; }
}
}
}
}
// Step 4: Create and write out the index file
OutputFile indexFile = createIndexFile(sHeading, entries);
if (!outdir.exists()) { outdir.mkdirs(); }
boolean bSuccess = true;
File outfile = new File(outdir,indexFile.getFileName());
try {
FileOutputStream fos = new FileOutputStream(outfile);
indexFile.write(fos);
fos.flush();
fos.close();
} catch (Exception writeExcept) {
bSuccess = false;
}
handler.endDirectory(indir.getPath(), bSuccess);
return !handler.cancel();
}
// Convert a single file, returning the name of the master file
// Returns null if conversion fails
private String convertFile(File infile, File outdir, BatchHandler handler) {
handler.startFile(infile.getPath());
// Currently we discriminate based on file extension
if (!(infile.getName().endsWith(".odt") || infile.getName().endsWith(".ods") || infile.getName().endsWith(".odp"))) {
handler.endFile(infile.getPath(),false);
return null;
}
// Do conversion
ConverterResult dataOut = null;
try {
// The target file name is always the same as the source
dataOut = converter.convert(infile,Misc.removeExtension(infile.getName()));
}
catch (FileNotFoundException e) {
handler.endFile(infile.getPath(),false);
return null;
}
catch (IOException e) {
handler.endFile(infile.getPath(),false);
return null;
}
// Write out files
if (!outdir.exists()) { outdir.mkdirs(); }
try {
dataOut.write(outdir);
}
catch (IOException e) {
handler.endFile(infile.getPath(),false);
return null;
}
handler.endFile(infile.getPath(),true);
return dataOut.iterator().next().getFileName();
}
}

View file

@ -0,0 +1,292 @@
/************************************************************************
*
* BibliographyGenerator.java
*
* Copyright: 2002-2018 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2018-03-06)
*
*/
package writer2latex.base;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import writer2latex.office.OfficeReader;
import writer2latex.office.XMLString;
import writer2latex.util.Misc;
import writer2latex.util.StringComparator;
/** This class is used to generate bibliographic references and a bibliography.
* Bibliographies are generated from a list of items (text:bibliograpy-mark), a global configuration
* (text:bibliography-configuration) and a formatting template (text:bibliography-source)
*/
public abstract class BibliographyGenerator {
// Bibliography configuration data
private String sPrefix = "[";
private String sSuffix = "]";
// The sorted list of bibliography marks
private List<Element> bibMarkList = new ArrayList<Element>();
// Map from key to label
private Map<String,String> bibMarkLabel = new HashMap<String,String>();
// Flag to identify numbering
private boolean bNumberedEntries = false;
// Flag to identify truncation of templates
private boolean bSkipKey = false;
/** Create a new bibliography generator based on a bibliography configuration and a list of bibliography marks
*
* @param ofr the office reader used to access the source document
* @param bSkipKey set to true if the key should be excluded when applying templates
*/
protected BibliographyGenerator(OfficeReader ofr, boolean bSkipKey) {
this.bSkipKey = bSkipKey;
Element bibConfig = ofr.getBibliographyConfiguration();
if (bibConfig!=null) {
if (bibConfig.hasAttribute(XMLString.TEXT_PREFIX)) {
sPrefix = bibConfig.getAttribute(XMLString.TEXT_PREFIX);
}
if (bibConfig.hasAttribute(XMLString.TEXT_SUFFIX)) {
sSuffix = bibConfig.getAttribute(XMLString.TEXT_SUFFIX);
}
}
collectBibMarks(ofr.getBibliographyMarks());
sortBibMarks(bibConfig);
createLabels(bibConfig);
}
// Collect the bibliography marks from the raw list, removing any duplicates
private void collectBibMarks(List<Element> bibMarks) {
Set<String> keys = new HashSet<String>();
for (Element bibMark : bibMarks) {
String sKey = bibMark.getAttribute(XMLString.TEXT_IDENTIFIER);
if (!keys.contains(sKey)) {
bibMarkList.add(bibMark);
keys.add(sKey);
}
}
}
// Sort the bibliography marks based on the settings in the bibliography configuration
private void sortBibMarks(Element bibConfig) {
if (bibConfig!=null && "false".equals(bibConfig.getAttribute(XMLString.TEXT_SORT_BY_POSITION))) {
// Get the sort algorithm
//String sSortAlgorithm = "alphanumeric";
//if (bibConfig.hasAttribute(XMLString.TEXT_SORT_ALGORITHM)) {
// sSortAlgorithm = bibConfig.getAttribute(XMLString.TEXT_SORT_ALGORITHM);
//}
// Get the sort keys
List<String> sortKeys = new ArrayList<String>();
List<Boolean> sortAscending = new ArrayList<Boolean>();
Node child = bibConfig.getFirstChild();
while (child!=null) {
if (child.getNodeType()==Node.ELEMENT_NODE && child.getNodeName().equals(XMLString.TEXT_SORT_KEY)) {
String sKey = Misc.getAttribute(child, XMLString.TEXT_KEY);
if (sKey!=null) {
sortKeys.add(sKey);
sortAscending.add(!"false".equals(Misc.getAttribute(child, XMLString.TEXT_SORT_ASCENDING)));
}
}
child = child.getNextSibling();
}
// Sort the list
Comparator<Element> comparator = new StringComparator<Element>(
Misc.getAttribute(bibConfig,XMLString.FO_LANGUAGE),
Misc.getAttribute(bibConfig, XMLString.FO_COUNTRY)) {
private List<String> sortKeys = null;
private List<Boolean> sortAscending = null;
Comparator<Element> setSortKeys(List<String> sortKeys, List<Boolean> sortAscending) {
this.sortKeys = sortKeys;
this.sortAscending = sortAscending;
return this;
}
public int compare(Element a, Element b) {
int nCount = sortKeys.size();
for (int i=0; i<nCount; i++) {
String sWorda = a.getAttribute("text:"+sortKeys.get(i));
String sWordb = b.getAttribute("text:"+sortKeys.get(i));
int nCompare = getCollator().compare(sWorda, sWordb)*(sortAscending.get(i) ? 1 : -1);
if (nCompare!=0) { return nCompare; }
}
return 0;
}
}.setSortKeys(sortKeys, sortAscending);
Collections.sort(bibMarkList, comparator);
}
}
private void createLabels(Element bibConfig) {
bNumberedEntries = bibConfig!=null && "true".equals(bibConfig.getAttribute(XMLString.TEXT_NUMBERED_ENTRIES));
int nCount = bibMarkList.size();
for (int i=0; i<nCount; i++) {
Element item = bibMarkList.get(i);
String sKey = item.getAttribute(XMLString.TEXT_IDENTIFIER);
if (bNumberedEntries) {
bibMarkLabel.put(sKey, Integer.toString(i+1));
}
else {
bibMarkLabel.put(sKey, sKey);
}
}
}
/** Get all labels used in the bibliography
*
* @return the set of labels
*/
protected Collection<String> getLabels() {
return bibMarkLabel.values();
}
/** Check whether entries are numbered rather than labeled with the key
*
* @return true if the entries are numbered
*/
protected boolean isNumberedEntries() {
return bNumberedEntries;
}
/** Get citation text for a reference to the bibliography
*
* @param sKey the key of the bibliography item
* @return the citation text to be shown in the document
*/
public String generateCitation(String sKey) {
return sPrefix+bibMarkLabel.get(sKey)+sSuffix;
}
/** Generate a bibliography
*
* @param bibSource a text:bibliography-source element
*/
protected void generateBibliography(Element bibSource) {
Map<String,Element> bibEntryTemplate = collectTemplates(bibSource);
for (Element bibMark : bibMarkList) {
String sKey = bibMark.getAttribute(XMLString.TEXT_IDENTIFIER);
String sType = bibMark.getAttribute(XMLString.TEXT_BIBLIOGRAPHY_TYPE);
if (bibEntryTemplate.containsKey(sType)) {
Element template = bibEntryTemplate.get(sType);
String sStyleName = template.getAttribute(XMLString.TEXT_STYLE_NAME);
insertBibliographyItem(sStyleName,sKey);
applyTemplate(template,bibMark);
}
else { // Use a default template (identical with the default template in LO)
String sAuthor = bibMark.getAttribute(XMLString.TEXT_AUTHOR);
String sTitle = bibMark.getAttribute(XMLString.TEXT_TITLE);
String sYear = bibMark.getAttribute(XMLString.TEXT_YEAR);
insertBibliographyItem(null,sKey);
if (!bSkipKey) {
insertBibliographyItemElement(null,bibMarkLabel.get(sKey));
insertBibliographyItemElement(null,": ");
}
insertBibliographyItemElement(null,sAuthor);
insertBibliographyItemElement(null,", ");
insertBibliographyItemElement(null,sTitle);
insertBibliographyItemElement(null,", ");
insertBibliographyItemElement(null,sYear);
}
}
}
private Map<String,Element> collectTemplates(Element bibSource) {
Map<String,Element> bibEntryTemplate = new HashMap<String,Element>();
Node child = bibSource.getFirstChild();
while (child!=null) {
if (child.getNodeType()==Node.ELEMENT_NODE
&& child.getNodeName().equals(XMLString.TEXT_BIBLIOGRAPHY_ENTRY_TEMPLATE)) {
String sType = Misc.getAttribute(child, XMLString.TEXT_BIBLIOGRAPHY_TYPE);
if (sType!=null) {
bibEntryTemplate.put(sType, (Element)child);
}
}
child = child.getNextSibling();
}
return bibEntryTemplate;
}
private void applyTemplate(Element template, Element bibMark) {
boolean bSkip = bSkipKey;
Node child = template.getFirstChild();
while (child!=null) {
if (child.getNodeType()==Node.ELEMENT_NODE) {
if (child.getNodeName().equals(XMLString.TEXT_INDEX_ENTRY_BIBLIOGRAPHY)) {
String sField = Misc.getAttribute(child, XMLString.TEXT_BIBLIOGRAPHY_DATA_FIELD);
if (sField!=null) {
String sValue = bibMark.getAttribute("text:"+sField);
if (sField.equals("identifier")) {
sValue = bibMarkLabel.get(sValue);
}
else {
bSkip = false;
}
if (!bSkip) {
String sElementStyleName = Misc.getAttribute(child,XMLString.TEXT_STYLE_NAME);
insertBibliographyItemElement(sElementStyleName,sValue);
}
}
}
else if (child.getNodeName().equals(XMLString.TEXT_INDEX_ENTRY_SPAN)) {
if (!bSkip) {
String sValue = Misc.getPCDATA(child);
String sElementStyleName = Misc.getAttribute(child,XMLString.TEXT_STYLE_NAME);
insertBibliographyItemElement(sElementStyleName,sValue);
}
}
}
child = child.getNextSibling();
}
}
/** Insert a new bibliography item
*
* @param sStyleName a paragraph style to apply to the item
* @param sKey the key of the bibliography item
*/
protected abstract void insertBibliographyItem(String sStyleName, String sKey);
/** Insert an element of a bibliography item
*
* @param sStyleName a character style to apply to the element
* @param sText the element text
*/
protected abstract void insertBibliographyItemElement(String sStyleName, String sText);
}

View file

@ -0,0 +1,179 @@
/************************************************************************
*
* BinaryGraphicsDocument.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-05-05)
*
*/
package writer2latex.base;
import java.io.OutputStream;
import java.io.IOException;
import writer2latex.api.OutputFile;
/** This class is used to represent a binary graphics document to be included in the converter result.
* I may also represent a linked image, which should <em>not</em> be included (and will produce an empty file
* if it is).
*/
public class BinaryGraphicsDocument implements OutputFile {
private String sFileName;
private String sMimeType;
private boolean bAcceptedFormat;
private boolean bRecycled = false;
// Data for an embedded image
private byte[] blob = null;
private int nOff = 0;
private int nLen = 0;
/**Constructs a new graphics document.
* Until data is added using the <code>read</code> methods, the document is considered a link to
* the image given by the file name.
*
* @param sFileName The name or URL of the <code>GraphicsDocument</code>.
* @param sMimeType the MIME type of the document
*/
public BinaryGraphicsDocument(String sFileName, String sMimeType) {
this.sFileName = sFileName;
this.sMimeType = sMimeType;
bAcceptedFormat = false; // or rather "don't know"
}
/** Construct a new graphics document which is a recycled version of the supplied one.
* This implies that all information is identical, but the recycled version does not contain any data.
* This is for images that are used more than once in the document.
*
* @param bgd the source document
*/
public BinaryGraphicsDocument(BinaryGraphicsDocument bgd) {
this.sFileName = bgd.getFileName();
this.sMimeType = bgd.getMIMEType();
this.bAcceptedFormat = bgd.isAcceptedFormat();
this.bRecycled = true;
}
/** Is this graphics document recycled?
*
* @return true if this is the case
*/
public boolean isRecycled() {
return bRecycled;
}
/** Set image contents to a byte array
*
* @param data the image data
* @param bIsAcceptedFormat flag to indicate that the format of the image is acceptable for the converter
*/
public void setData(byte[] data, boolean bIsAcceptedFormat) {
setData(data,0,data.length,bIsAcceptedFormat);
}
/** Set image contents to part of a byte array
*
* @param data the image data
* @param nOff the offset into the byte array
* @param nLen the number of bytes to use
* @param bIsAcceptedFormat flag to indicate that the format of the image is acceptable for the converter
*/
public void setData(byte[] data, int nOff, int nLen, boolean bIsAcceptedFormat) {
this.blob = data;
this.nOff = nOff;
this.nLen = nLen;
this.bAcceptedFormat = bIsAcceptedFormat;
}
/** Does this <code>BinaryGraphicsDocument</code> represent a linked image?
*
* @return true if so
*/
public boolean isLinked() {
return blob==null && !bRecycled;
}
/** Is this image in an acceptable format for the converter?
*
* @return true if so (always returns false for linked images)
*/
public boolean isAcceptedFormat() {
return bAcceptedFormat;
}
/** Get the data of the image
*
* @return the image data as a byte array - or null if this is a linked image
*/
public byte[] getData() {
return blob;
}
// Implement OutputFile
/** Writes out the content to the specified <code>OutputStream</code>.
* Linked images will not write any data.
*
* @param os <code>OutputStream</code> to write out the content.
*
* @throws IOException If any I/O error occurs.
*/
public void write(OutputStream os) throws IOException {
if (blob!=null) {
os.write(blob, nOff, nLen);
}
}
/** Get the document name or URL</p>
*
* @return The document name or URL
*/
public String getFileName() {
return sFileName;
}
/** Get the MIME type of the document.
*
* @return The MIME type or null if this is unknown
*/
public String getMIMEType() {
return sMimeType;
}
/** Is this document a master document?
*
* @return false - a graphics file is never a master document
*/
public boolean isMasterDocument() {
return false;
}
/** Does this document contain formulas?
*
* @return false - a graphics file does not contain formulas
*/
public boolean containsMath() {
return false;
}
}

View file

@ -0,0 +1,43 @@
/************************************************************************
*
* BooleanOption.java
*
* Copyright: 2002-2008 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.0 (2008-09-08)
*
*/
package writer2latex.base;
// A BooleanOption interprets the values as booleans
public class BooleanOption extends Option {
private boolean bValue;
public boolean getValue() { return bValue; }
public void setString(String sValue) {
super.setString(sValue);
bValue = "true".equals(sValue);
}
public BooleanOption(String sName, String sDefaultValue) {
super(sName,sDefaultValue);
}
}

View file

@ -0,0 +1,187 @@
/************************************************************************
*
* ConfigBase.java
*
* Copyright: 2002-2014 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.4 (2014-08-26)
*
*/
package writer2latex.base;
/** Base implementation of writer2latex.api.Config
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.w3c.dom.DOMImplementation;
import writer2latex.api.ComplexOption;
public abstract class ConfigBase implements writer2latex.api.Config {
protected abstract int getOptionCount();
protected abstract String getDefaultConfigPath();
protected Option[] options;
protected Map<String,ComplexOption> optionGroups;
public ConfigBase() {
options = new Option[getOptionCount()];
optionGroups = new HashMap<String,ComplexOption>();
}
public void setOption(String sName,String sValue) {
if (sName!=null && sValue!=null) {
for (int j=0; j<getOptionCount(); j++) {
if (sName.equals(options[j].getName())) {
options[j].setString(sValue);
break;
}
}
}
}
public String getOption(String sName) {
if (sName!=null) {
for (int j=0; j<getOptionCount(); j++) {
if (sName.equals(options[j].getName())) {
return options[j].getString();
}
}
}
return null;
}
public ComplexOption getComplexOption(String sGroup) {
return optionGroups.get(sGroup);
}
// The subclass may use this method to define option groups
protected ComplexOption addComplexOption(String sGroup) {
optionGroups.put(sGroup, new ComplexOption());
return optionGroups.get(sGroup);
}
public void readDefaultConfig(String sName) throws IllegalArgumentException {
InputStream is = this.getClass().getResourceAsStream(getDefaultConfigPath()+sName);
if (is==null) {
throw new IllegalArgumentException("The internal configuration '"+sName+ "' does not exist");
}
try {
read(is);
}
catch (IOException e) {
// This would imply a bug in the configuration file!
throw new IllegalArgumentException("The internal configuration '"+sName+ "' is invalid");
}
}
/** <p>Read configuration from a specified input stream</p>
* @param is the input stream to read the configuration from
*/
public void read(InputStream is) throws IOException {
DOMDocument doc = new DOMDocument("config",".xml");
doc.read(is); // may throw an IOException
Document dom = doc.getContentDOM();
if (dom==null) {
throw new IOException("Failed to parse configuration");
}
Node root = dom.getDocumentElement();
Node child = root.getFirstChild();
while (child!=null) {
if (child.getNodeType()==Node.ELEMENT_NODE) {
Element elm = (Element)child;
if (elm.getTagName().equals("option")) {
String sName = elm.getAttribute("name");
String sValue = elm.getAttribute("value");
if (sName.length()>0) { setOption(sName,sValue); }
}
else {
readInner(elm);
}
}
child = child.getNextSibling();
}
}
public void read(File file) throws IOException {
read(new FileInputStream(file));
}
/** Read configuration information from an xml element.
* The subclass must define this to read richer configuration data
*/
protected abstract void readInner(Element elm);
public void write(OutputStream os) throws IOException {
DOMDocument doc = new DOMDocument("config",".xml");
Document dom = null;
try {
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
DOMImplementation domImpl = builder.getDOMImplementation();
dom = domImpl.createDocument("","config",null);
} catch (ParserConfigurationException e) {
// This will not happen
e.printStackTrace();
return;
}
Element rootElement = dom.getDocumentElement();
for (int i=0; i<getOptionCount(); i++) {
Element optionNode = dom.createElement("option");
optionNode.setAttribute("name",options[i].getName());
optionNode.setAttribute("value",options[i].getString());
rootElement.appendChild(optionNode);
}
writeInner(dom);
doc.setContentDOM(dom);
doc.write(os); // may throw an IOException
}
public void write(File file) throws IOException {
write(new FileOutputStream(file));
}
/** Write configuration information to an xml document.
* The subclass must define this to write richer configuration data
*/
protected abstract void writeInner(Document dom);
}

View file

@ -0,0 +1,59 @@
/************************************************************************
*
* ConverterResultImpl.java
*
* Copyright: 2002-2010 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.2 (2010-03-24)
*
*/
package writer2latex.base;
import writer2latex.api.ContentEntry;
import writer2latex.api.OutputFile;
public class ContentEntryImpl implements ContentEntry {
private String sTitle;
private int nLevel;
private OutputFile file;
private String sTarget;
public ContentEntryImpl(String sTitle, int nLevel, OutputFile file, String sTarget) {
this.sTitle = sTitle;
this.nLevel = nLevel;
this.file = file;
this.sTarget = sTarget;
}
public String getTitle() {
return sTitle;
}
public int getLevel() {
return nLevel;
}
public OutputFile getFile() {
return file;
}
public String getTarget() {
return sTarget;
}
}

View file

@ -0,0 +1,183 @@
/************************************************************************
*
* ConverterBase.java
*
* Copyright: 2002-2014 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.4 (2014-09-03)
*
*/
package writer2latex.base;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.IOException;
import org.w3c.dom.Element;
import writer2latex.api.GraphicConverter;
import writer2latex.api.Converter;
import writer2latex.api.ConverterResult;
import writer2latex.api.OutputFile;
import writer2latex.office.EmbeddedObject;
import writer2latex.office.MetaData;
import writer2latex.office.OfficeDocument;
import writer2latex.office.OfficeReader;
import writer2latex.office.XMLString;
import writer2latex.util.Misc;
/**<p>Abstract base implementation of <code>writer2latex.api.Converter</code></p>
*/
public abstract class ConverterBase implements Converter {
public enum TexMathsStyle {inline, display, latex};
// Helper
protected GraphicConverter graphicConverter;
// The source document
protected OfficeDocument odDoc;
protected OfficeReader ofr;
protected MetaData metaData;
protected ImageConverter imageConverter;
// The output file(s)
protected String sTargetFileName;
protected ConverterResultImpl converterResult;
// Constructor
public ConverterBase() {
graphicConverter = null;
converterResult = new ConverterResultImpl();
}
// Implement the interface
public void setGraphicConverter(GraphicConverter graphicConverter) {
this.graphicConverter = graphicConverter;
}
// Provide a do noting fallback method
public void readTemplate(InputStream is) throws IOException { }
// Provide a do noting fallback method
public void readTemplate(File file) throws IOException { }
// Provide a do noting fallback method
public void readStyleSheet(InputStream is) throws IOException { }
// Provide a do noting fallback method
public void readStyleSheet(File file) throws IOException { }
// Provide a do noting fallback method
public void readResource(InputStream is, String sFileName, String sMediaType) throws IOException { }
// Provide a do noting fallback method
public void readResource(File file, String sFileName, String sMediaType) throws IOException { }
public ConverterResult convert(File source, String sTargetFileName) throws FileNotFoundException,IOException {
return convert(new FileInputStream(source), sTargetFileName);
}
public ConverterResult convert(InputStream is, String sTargetFileName) throws IOException {
// Read document
odDoc = new OfficeDocument();
odDoc.read(is);
return convert(sTargetFileName,true);
}
public ConverterResult convert(org.w3c.dom.Document dom, String sTargetFileName, boolean bDestructive) throws IOException {
// Read document
odDoc = new OfficeDocument();
odDoc.read(dom);
return convert(sTargetFileName,bDestructive);
}
private ConverterResult convert(String sTargetFileName, boolean bDestructive) throws IOException {
ofr = new OfficeReader(odDoc,false);
metaData = new MetaData(odDoc);
imageConverter = new ImageConverter(ofr,bDestructive,true);
imageConverter.setGraphicConverter(graphicConverter);
// Prepare output
this.sTargetFileName = sTargetFileName;
converterResult.reset();
converterResult.setMetaData(metaData);
if (metaData.getLanguage()==null || metaData.getLanguage().length()==0) {
metaData.setLanguage(ofr.getMajorityLanguage());
}
convertInner();
return converterResult;
}
// The subclass must provide the implementation
public abstract void convertInner() throws IOException;
public MetaData getMetaData() { return metaData; }
public ImageConverter getImageCv() { return imageConverter; }
public void addDocument(OutputFile doc) { converterResult.addDocument(doc); }
public EmbeddedObject getEmbeddedObject(String sHref) {
return odDoc.getEmbeddedObject(sHref);
}
/** Get a TexMaths equation from a draw:frame (PNG formula) or draw:g element (SVG)
* Such an element is a TexMaths equation if it contains an svg:title element with content "TexMaths"
* The actual formula is the content of an svg:desc element
*
* @param node the draw:frame or draw:g element to check
* @return the TexMaths equation, or null if this is not a TexMaths equation
*/
public Element getTexMathsEquation(Element node) {
Element svgTitle = Misc.getChildByTagName(node, XMLString.SVG_TITLE);
if (svgTitle!=null && "TexMaths".equals(Misc.getPCDATA(svgTitle))) {
return Misc.getChildByTagName(node, XMLString.SVG_DESC);
}
return null;
}
public TexMathsStyle getTexMathsStyle(String s) {
String[] sContent = s.split("\u00a7");
if (sContent.length>=3) { // we only need 3 items of 6
if ("display".equals(sContent[1])) {
return TexMathsStyle.display;
}
else if ("latex".equals(sContent[1]) || "text".equals(sContent[1])) { // text is for OOoLaTeX
return TexMathsStyle.latex;
}
}
return TexMathsStyle.inline;
}
public String getTexMathsEquation(String s) {
String[] sContent = s.split("\u00a7");
if (sContent.length>=3) { // we only need 3 items of 6
return sContent[2];
}
else {
return "";
}
}
}

View file

@ -0,0 +1,282 @@
/************************************************************************
*
* ConverterResultImpl.java
*
* Copyright: 2002-2011 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.2 (2011-07-20)
*
*/
package writer2latex.base;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Vector;
import java.util.Iterator;
import writer2latex.api.ConverterResult;
import writer2latex.api.MetaData;
import writer2latex.api.OutputFile;
import writer2latex.api.ContentEntry;
/** <code>ConverterResultImpl</code> is a straightforward implementation of <code>ConverterResult</code>
*/
public class ConverterResultImpl implements ConverterResult {
private List<OutputFile> files;
private List<ContentEntry> content;
private ContentEntry titlePageFile;
private ContentEntry textFile;
private ContentEntry tocFile;
private ContentEntry lofFile;
private ContentEntry lotFile;
private ContentEntry indexFile;
private ContentEntry bibliographyFile;
private ContentEntry coverFile;
private ContentEntry coverImageFile;
private MetaData metaData = null;
private int nMasterCount;
/** Construct a new <code>ConverterResultImpl</code> with empty content
*/
public ConverterResultImpl() {
reset();
}
/** Resets all data. This empties all <code>OutputFile</code> and <code>ContentEntry</code> objects
* objects from this class. This allows reuse of a <code>ConvertResult</code> object.
*/
public void reset() {
files = new Vector<OutputFile>();
content = new Vector<ContentEntry>();
titlePageFile = null;
textFile = null;
tocFile = null;
lofFile = null;
lotFile = null;
indexFile = null;
bibliographyFile = null;
coverImageFile = null;
metaData = null;
nMasterCount = 0;
}
/** Adds an <code>OutputFile</code> to the list
*
* @param file The <code>OutputFile</code> to add.
*/
public void addDocument(OutputFile file) {
if (file.isMasterDocument()) {
files.add(nMasterCount++, file);
}
else {
files.add(file);
}
}
/** Get the first master document
*
* @return <code>OutputFile</code> the master document
*/
public OutputFile getMasterDocument() {
return files.size()>0 ? files.get(0) : null;
}
/**
* Gets an <code>Iterator</code> to access the <code>List</code>
* of <code>OutputFile</code> objects
*
* @return The <code>Iterator</code> to access the
* <code>List</code> of <code>OutputFile</code> objects.
*/
public Iterator<OutputFile> iterator() {
return files.iterator();
}
/** Add an entry to the "external" table of contents
*
* @param entry the entry to add
*/
public void addContentEntry(ContentEntry entry) {
content.add(entry);
}
public List<ContentEntry> getContent() {
return Collections.unmodifiableList(content);
}
/** Define the entry which contains the title page
*
* @param entry the entry
*/
public void setTitlePageFile(ContentEntry entry) {
titlePageFile = entry;
}
public ContentEntry getTitlePageFile() {
return titlePageFile;
}
/** Define the entry which contains the main text file
*
* @param entry the entry
*/
public void setTextFile(ContentEntry entry) {
textFile = entry;
}
public ContentEntry getTextFile() {
return textFile;
}
/** Define the entry which contains the table of contents
*
* @param entry the entry
*/
public void setTocFile(ContentEntry entry) {
tocFile = entry;
}
public ContentEntry getTocFile() {
return tocFile;
}
/** Define the entry which contains the list of figures
*
* @param entry the entry
*/
public void setLofFile(ContentEntry entry) {
lofFile = entry;
}
public ContentEntry getLofFile() {
return lofFile;
}
/** Define the entry which contains the list of tables
*
* @param entry the entry
*/
public void setLotFile(ContentEntry entry) {
lotFile = entry;
}
public ContentEntry getLotFile() {
return lotFile;
}
/** Define the entry which contains the alphabetical index
*
* @param entry the entry
*/
public void setIndexFile(ContentEntry entry) {
indexFile = entry;
}
public ContentEntry getIndexFile() {
return indexFile;
}
/** Define the entry which contains the bibliography
*
* @param entry the entry
*/
public void setBibliographyFile(ContentEntry entry) {
bibliographyFile = entry;
}
public ContentEntry getBibliographyFile() {
return bibliographyFile;
}
/** Define the entry which contains the cover
*
* @param entry the entry
*/
public void setCoverFile(ContentEntry entry) {
coverFile = entry;
}
public ContentEntry getCoverFile() {
return coverFile;
}
/** Define the entry which contains the cover image
*
* @param entry the entry
*/
public void setCoverImageFile(ContentEntry entry) {
coverImageFile = entry;
}
public ContentEntry getCoverImageFile() {
return coverImageFile;
}
/** Set the meta data of this <code>ConverterResult</code>
*
* @param metaData the meta data
*/
public void setMetaData(MetaData metaData) {
this.metaData = metaData;
}
/** Get the meta data of this <code>ConverterResult</code>
*
* @return the meta data
*/
public MetaData getMetaData() {
return metaData;
}
/** Write all files to a given directory
*
* @param dir the directory to use
*/
public void write(File dir) throws IOException {
if (dir!=null && !dir.exists()) throw new IOException("Directory does not exist");
Iterator<OutputFile> docEnum = iterator();
while (docEnum.hasNext()) {
OutputFile docOut = docEnum.next();
String sDirName = "";
String sFileName = docOut.getFileName();
File subdir = dir;
int nSlash = sFileName.indexOf("/");
if (nSlash>-1) {
sDirName = sFileName.substring(0,nSlash);
sFileName = sFileName.substring(nSlash+1);
subdir = new File(dir,sDirName);
if (!subdir.exists()) { subdir.mkdir(); }
}
File outfile = new File (subdir,sFileName);
FileOutputStream fos = new FileOutputStream(outfile);
docOut.write(fos);
fos.flush();
fos.close();
}
}
}

View file

@ -0,0 +1,369 @@
/************************************************************************
*
* DOMDocument.java
*
* Copyright: 2002-2015 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2015-05-05)
*
*/
package writer2latex.base;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
//import org.xml.sax.SAXParseException;
import writer2latex.api.OutputFile;
/**
* This class represents XML-based documents. It is loosely based on a class from the former xmerge project
* from OOo.
*/
public class DOMDocument implements OutputFile {
/** Factory for <code>DocumentBuilder</code> objects. */
private static DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
/** DOM <code>Document</code> of content.xml. */
private Document contentDoc = null;
/** DOM <code>Document</code> of styles.xml. */
//private Document styleDoc = null;
private String documentName = null;
private String fileName = null;
private String fileExt = null;
/** Resources object. */
//private Resources res = null;
/**
* Default constructor.
*
* @param name <code>Document</code> name.
* @param ext <code>Document</code> extension.
*/
public DOMDocument(String name,String ext)
{
this(name,ext,true, false);
}
/**
* Returns the file extension of the <code>Document</code>
* represented.
*
* @return file extension of the <code>Document</code>.
*/
protected String getFileExtension() {
return fileExt;
}
/**
* Constructor with arguments to set <code>namespaceAware</code>
* and <code>validating</code> flags.
*
* @param name <code>Document</code> name (may or may not
* contain extension).
* @param ext <code>Document</code> extension.
* @param namespaceAware Value for <code>namespaceAware</code> flag.
* @param validating Value for <code>validating</code> flag.
*/
public DOMDocument(String name, String ext,boolean namespaceAware, boolean validating) {
//res = Resources.getInstance();
factory.setValidating(validating);
factory.setNamespaceAware(namespaceAware);
this.fileExt = ext;
this.documentName = trimDocumentName(name);
this.fileName = documentName + getFileExtension();
}
/**
* Removes the file extension from the <code>Document</code>
* name.
*
* @param name Full <code>Document</code> name with extension.
*
* @return Name of <code>Document</code> without the extension.
*/
private String trimDocumentName(String name) {
String temp = name.toLowerCase();
String ext = getFileExtension();
if (temp.endsWith(ext)) {
// strip the extension
int nlen = name.length();
int endIndex = nlen - ext.length();
name = name.substring(0,endIndex);
}
return name;
}
/**
* Return a DOM <code>Document</code> object of the document content
* file. Note that a content DOM is not created when the constructor
* is called. So, either the <code>read</code> method or the
* <code>initContentDOM</code> method will need to be called ahead
* on this object before calling this method.
*
* @return DOM <code>Document</code> object.
*/
public Document getContentDOM() {
return contentDoc;
}
/**
* Sets the Content of the <code>Document</code> to the contents of the
* supplied <code>Node</code> list.
*
* @param newDom DOM <code>Document</code> object.
*/
public void setContentDOM( Node newDom) {
contentDoc=(Document)newDom;
}
/**
* Return the name of the <code>Document</code>.
*
* @return The name of <code>Document</code>.
*/
public String getName() {
return documentName;
}
/**
* Return the file name of the <code>Document</code>, possibly
* with the standard extension.
*
* @return The file name of <code>Document</code>.
*/
public String getFileName() {
return fileName;
}
/**
* Read the Office <code>Document</code> from the specified
* <code>InputStream</code>.
*
* @param is Office document <code>InputStream</code>.
*
* @throws IOException If any I/O error occurs.
*/
public void read(InputStream is) throws IOException {
DocumentBuilder builder = null;
try {
builder = factory.newDocumentBuilder();
} catch (ParserConfigurationException ex) {
throw new IOException(ex.getMessage());
}
try {
contentDoc= builder.parse(is);
} catch (SAXException ex) {
throw new IOException(ex.getMessage());
}
}
/**
* Write out content to the supplied <code>OutputStream</code>.
* (with pretty printing)
* @param os XML <code>OutputStream</code>.
* @throws IOException If any I/O error occurs.
*/
public void write(OutputStream os) throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(os,"UTF-8");
osw.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
write(getContentDOM().getDocumentElement(),0,osw);
osw.flush();
osw.close();
}
// Write nodes; we only need element, text and comment nodes
private void write(Node node, int nLevel, OutputStreamWriter osw) throws IOException {
short nType = node.getNodeType();
switch (nType) {
case Node.ELEMENT_NODE:
if (node.hasChildNodes()) {
// Block pretty print from this node?
NodeList list = node.getChildNodes();
int nLen = list.getLength();
boolean bBlockPrettyPrint = false;
if (nLevel>=0) {
for (int i = 0; i < nLen; i++) {
bBlockPrettyPrint |= list.item(i).getNodeType()==Node.TEXT_NODE;
}
}
// Print start tag
if (nLevel>=0) { writeSpaces(nLevel,osw); }
osw.write("<"+node.getNodeName());
writeAttributes(node,osw);
osw.write(">");
if (nLevel>=0 && !bBlockPrettyPrint) { osw.write("\n"); }
// Print children
for (int i = 0; i < nLen; i++) {
int nNextLevel;
if (bBlockPrettyPrint || nLevel<0) { nNextLevel=-1; }
else { nNextLevel=nLevel+1; }
write(list.item(i),nNextLevel,osw);
}
// Print end tag
if (nLevel>=0 && !bBlockPrettyPrint) { writeSpaces(nLevel,osw); }
osw.write("</"+node.getNodeName()+">");
if (nLevel>=0) { osw.write("\n"); }
}
else { // empty element
if (nLevel>=0) { writeSpaces(nLevel,osw); }
osw.write("<"+node.getNodeName());
writeAttributes(node,osw);
osw.write(" />");
if (nLevel>=0) { osw.write("\n"); }
}
break;
case Node.TEXT_NODE:
write(node.getNodeValue(),osw);
break;
case Node.COMMENT_NODE:
if (nLevel>=0) { writeSpaces(nLevel,osw); }
osw.write("<!-- ");
write(node.getNodeValue(),osw);
osw.write(" -->");
if (nLevel>=0) { osw.write("\n"); }
}
}
private void writeAttributes(Node node, OutputStreamWriter osw) throws IOException {
NamedNodeMap attr = node.getAttributes();
int nLen = attr.getLength();
for (int i=0; i<nLen; i++) {
Node item = attr.item(i);
osw.write(" ");
write(item.getNodeName(),osw);
osw.write("=\"");
write(item.getNodeValue(),osw);
osw.write("\"");
}
}
private void writeSpaces(int nCount, OutputStreamWriter osw) throws IOException {
for (int i=0; i<nCount; i++) { osw.write(" "); }
}
private void write(String s, OutputStreamWriter osw) throws IOException {
int nLen = s.length();
char c;
for (int i=0; i<nLen; i++) {
c = s.charAt(i);
switch (c) {
case ('<'): osw.write("&lt;"); break;
case ('>'): osw.write("&gt;"); break;
case ('&'): osw.write("&amp;"); break;
case ('"'): osw.write("&quot;"); break;
case ('\''): osw.write( "&apos;"); break;
default: osw.write(c);
}
}
}
/**
* Initializes a new DOM <code>Document</code> with the content
* containing minimum XML tags.
*
* @throws IOException If any I/O error occurs.
*/
public final void initContentDOM() throws IOException {
contentDoc = createDOM("");
}
/**
* <p>Creates a new DOM <code>Document</code> containing minimum
* OpenOffice XML tags.</p>
*
* <p>This method uses the subclass
* <code>getOfficeClassAttribute</code> method to get the
* attribute for <i>office:class</i>.</p>
*
* @param rootName root name of <code>Document</code>.
*
* @throws IOException If any I/O error occurs.
*/
private final Document createDOM(String rootName) throws IOException {
Document doc = null;
try {
DocumentBuilder builder = factory.newDocumentBuilder();
doc = builder.newDocument();
} catch (ParserConfigurationException ex) {
// This will not happen
System.err.println("Error:"+ ex);
throw new IOException(ex);
}
Element root = (Element) doc.createElement(rootName);
doc.appendChild(root);
return doc;
}
// We need these because we implement OutputFile
public String getMIMEType() {
return "";
}
public boolean isMasterDocument() {
return false;
}
public boolean containsMath() {
return false;
}
}

View file

@ -0,0 +1,354 @@
/************************************************************************
*
* ImageConverter.java
*
* Copyright: 2002-2014 by Henrik Just
*
* This file is part of Writer2LaTeX.
*
* Writer2LaTeX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Writer2LaTeX 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Writer2LaTeX. If not, see <http://www.gnu.org/licenses/>.
*
* Version 1.6 (2014-11-18)
*
*/
package writer2latex.base;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import javax.xml.bind.DatatypeConverter;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import writer2latex.api.GraphicConverter;
import writer2latex.office.EmbeddedBinaryObject;
import writer2latex.office.EmbeddedObject;
import writer2latex.office.MIMETypes;
import writer2latex.office.OfficeReader;
import writer2latex.office.SVMReader;
import writer2latex.office.XMLString;
import writer2latex.util.Misc;
/** This class extracts and converts images from an office document.
* The images are returned as <code>BinaryGraphicsDocument</code>.
* The image converter can be configured as destructive. In this case, the returned
* graphics documents will contain the only reference to the image (the original data
* will be removed).
*/
public final class ImageConverter {
private OfficeReader ofr;
private boolean bDestructive;
// Data for file name generation
private String sBaseFileName = "";
private String sSubDirName = "";
private int nImageCount = 0;
private NumberFormat formatter;
// should EPS be extracted from SVM?
private boolean bExtractEPS;
// Data for image conversion
private GraphicConverter gcv = null;
private boolean bAcceptOtherFormats = true;
private String sDefaultFormat = null;
private String sDefaultVectorFormat = null;
private HashSet<String> acceptedFormats = new HashSet<String>();
// In the package format, the same image file may be used more than once in the document
// Hence we keep information of all documents for potential
private HashMap<String,BinaryGraphicsDocument> recycledImages = new HashMap<String,BinaryGraphicsDocument>();
/** Construct a new <code>ImageConverter</code> referring to a specific document
*
* @param ofr the office reader to use
* @param bExtractEPS set true if EPS content should be extracted from SVM files
*/
public ImageConverter(OfficeReader ofr, boolean bDestructive, boolean bExtractEPS) {
this.ofr = ofr;
this.bDestructive = bDestructive;
this.bExtractEPS = bExtractEPS;
this.formatter = new DecimalFormat("000");
}
/** Define the base file name to use for generating file names
*
* @param sBaseFileName the base file name
*/
public void setBaseFileName(String sBaseFileName) {
this.sBaseFileName = sBaseFileName;
}
/** Define the name of a sub directory to prepend to file names
*
* @param sSubDirName the sub directory
*/
public void setUseSubdir(String sSubDirName) {
this.sSubDirName = sSubDirName+"/";
}
/** Specify that the <code>ImageConverter</code> should return an image even if it was not possible
* to convert it to an acceptable format.
*
* @param b true if other formats should be accepted
*/
public void setAcceptOtherFormats(boolean b) {
bAcceptOtherFormats = b;
}
/** Define the default format for raster graphics
*
* @param sMime the MIME type of the default raster format
*/
public void setDefaultFormat(String sMime) {
addAcceptedFormat(sMime);
sDefaultFormat = sMime;
}
/** Define the default format for vector graphics
*
* @param sMime the MIME type for the default vector format
*/
public void setDefaultVectorFormat(String sMime) {
addAcceptedFormat(sMime);
sDefaultVectorFormat = sMime;
}
/** Define an accepted graphics format
*
* @param sMime the MIME type of the format
*/
public void addAcceptedFormat(String sMime) {
acceptedFormats.add(sMime);
}
/** Is a given format accepted?
*
* @param sMime the MIME type to query
* @return true if this is an accepted format
*/
private boolean isAcceptedFormat(String sMime) {
return acceptedFormats.contains(sMime);
}
/** Define the <code>GraphicConverter</code> to use for image conversion
*
* @param gcv the graphics converter
*/
public void setGraphicConverter(GraphicConverter gcv) {
this.gcv = gcv;
}
/** Get an image from a <code>draw:image</code> element. If the converter is destructive, the returned
* <code>BinaryGraphicsDocument</code> will hold the only reference to the image data (the original
* data will be removed).
*
* @param node the image element
* @return a document containing the (converted) image, or null if it was not possible to read the image
* or convert it to an accepted format
*/
public BinaryGraphicsDocument getImage(Element node) {
String sName = sSubDirName+sBaseFileName+formatter.format(++nImageCount);
BinaryGraphicsDocument bgd = getImage(node,sName);
if (bgd!=null) {
if (!bgd.isAcceptedFormat() || (sDefaultVectorFormat!=null && !sDefaultVectorFormat.equals(bgd.getMIMEType()))) {
// We may have better luck with an alternative image
Element sibling = getAlternativeImage(node);
if (sibling!=null) {
BinaryGraphicsDocument altBgd = getImage(sibling,sName);
if (altBgd!=null && altBgd.isAcceptedFormat()) {
if (!bgd.isAcceptedFormat() ||
(sDefaultVectorFormat!=null && !sDefaultVectorFormat.equals(bgd.getMIMEType()) &&
sDefaultVectorFormat.equals(altBgd.getMIMEType()))) {
bgd = altBgd;
}
}
}
}
}
if (bgd==null || bgd.isLinked() || bgd.isRecycled()) {
// The file name was not used
nImageCount--;
}
return bgd;
}
private BinaryGraphicsDocument getImage(Element node, String sName) {
assert(XMLString.DRAW_IMAGE.equals(node.getTagName()));
// Image data
String sExt = null;
String sMIME = null;
byte[] blob = null;
String sId = null;
// First try to extract the image using the xlink:href attribute
if (node.hasAttribute(XMLString.XLINK_HREF)) {
String sHref = node.getAttribute(XMLString.XLINK_HREF);
if (sHref.length()>0) {
// We may have seen this image before, return the recycled version
if (recycledImages.containsKey(sHref)) {
return recycledImages.get(sHref);
}
// Image may be embedded in package:
String sPath = sHref;
if (sPath.startsWith("#")) { sPath = sPath.substring(1); }
if (sPath.startsWith("./")) { sPath = sPath.substring(2); }
EmbeddedObject obj = ofr.getEmbeddedObject(sPath);
if (obj!=null && obj instanceof EmbeddedBinaryObject) {
EmbeddedBinaryObject object = (EmbeddedBinaryObject) obj;
blob = object.getBinaryData();
sMIME = object.getType();
if (sMIME.length()==0) {
// If the manifest provides a media type, trust that
// Otherwise determine it by byte inspection
sMIME = MIMETypes.getMagicMIMEType(blob);
}
sExt = MIMETypes.getFileExtension(sMIME);
if (bDestructive) {
object.dispose();
}
// We got an image, define ID for recycling
sId = sHref;
}
else {
// This is a linked image
// TODO: Add option to download image from the URL?
String sFileName = ofr.fixRelativeLink(sHref);
BinaryGraphicsDocument bgd
= new BinaryGraphicsDocument(sFileName,null);
return bgd;
}
}
}
// If there is no suitable xlink:href attribute, the image must be contained in an office:binary-element as base64
if (blob==null) {
Node obd = Misc.getChildByTagName(node,XMLString.OFFICE_BINARY_DATA);
if (obd!=null) {
StringBuilder buf = new StringBuilder();
NodeList nl = obd.getChildNodes();
int nLen = nl.getLength();
for (int i=0; i<nLen; i++) {
if (nl.item(i).getNodeType()==Node.TEXT_NODE) {
buf.append(nl.item(i).getNodeValue());
}
}
//blob = Base64.decode(buf.toString());
blob = DatatypeConverter.parseBase64Binary(buf.toString());
// We may have seen this image before, return the recycled version
String sId1 = createId(blob);
if (recycledImages.containsKey(sId1)) {
return recycledImages.get(sId1);
}
sMIME = MIMETypes.getMagicMIMEType(blob);
sExt = MIMETypes.getFileExtension(sMIME);
if (bDestructive) {
node.removeChild(obd);
}
// We got an image, define ID for recycling
sId = sId1;
}
else {
// There is no image data
return null;
}
}
// Is this an EPS file embedded in an SVM file?
// (This case is obsolete, but kept for the sake of old documents)
if (bExtractEPS && MIMETypes.SVM.equals(sMIME)) {
// Look for postscript:
int[] offlen = new int[2];
if (SVMReader.readSVM(blob,offlen)) {
String sFileName = sName+MIMETypes.EPS_EXT;
BinaryGraphicsDocument bgd
= new BinaryGraphicsDocument(sFileName, MIMETypes.EPS);
bgd.setData(blob,offlen[0],offlen[1],true);
return bgd;
}
}
// We have an embedded image.
// If we have a converter AND a default format AND this image
// is not in an accepted format AND the converter knows how to
// convert it - try to convert...
if (gcv!=null && !isAcceptedFormat(sMIME) && sDefaultFormat!=null) {
byte[] newBlob = null;
String sTargetMIME = null;
if (MIMETypes.isVectorFormat(sMIME) && sDefaultVectorFormat!=null &&
gcv.supportsConversion(sMIME,sDefaultVectorFormat,false,false)) {
// Try vector format first
newBlob = gcv.convert(blob, sMIME, sTargetMIME=sDefaultVectorFormat);
}
if (newBlob==null && gcv.supportsConversion(sMIME,sDefaultFormat,false,false)) {
// Then try bitmap format
newBlob = gcv.convert(blob,sMIME,sTargetMIME=sDefaultFormat);
}
if (newBlob!=null) {
// Conversion successful - create new data
blob = newBlob;
sMIME = sTargetMIME;
sExt = MIMETypes.getFileExtension(sMIME);
}
}
// Create the result
if (isAcceptedFormat(sMIME) || bAcceptOtherFormats) {
String sFileName = sName+sExt;
BinaryGraphicsDocument bgd = new BinaryGraphicsDocument(sFileName,sMIME);
bgd.setData(blob,isAcceptedFormat(sMIME));
if (sId!=null) {
recycledImages.put(sId, new BinaryGraphicsDocument(bgd));
}
return bgd;
}
else {
return null;
}
}
private Element getAlternativeImage(Element node) {
Node sibling = node.getNextSibling();
if (sibling!=null && Misc.isElement(sibling, XMLString.DRAW_IMAGE)) {
return (Element) sibling;
}
return null;
}
// Create a fingerprint of a blob. The fingerprint concatenates the MD5 hash with the first 10 bytes of the blob.
private String createId(byte[] blob) {
MessageDigest md;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
// This would be surprising
return null;
}
return DatatypeConverter.printHexBinary(md.digest(blob))
+DatatypeConverter.printHexBinary(Arrays.copyOf(blob, 10));
}
}

Some files were not shown because too many files have changed in this diff Show more