BibTeX support

git-svn-id: svn://svn.code.sf.net/p/writer2latex/code/trunk@229 f0f2a975-2e09-46c8-9428-3b39399b9f3c
This commit is contained in:
henrikjust 2015-02-16 14:48:25 +00:00
parent bc2f47a4a0
commit e16d5edd12
6 changed files with 306 additions and 189 deletions

View file

@ -16,11 +16,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Copyright: 2002-2008 by Henrik Just
* Copyright: 2002-2015 by Henrik Just
*
* All Rights Reserved.
*
* Version 1.0 (2008-07-21)
* Version 1.6 (2015-02-16)
*
*/
@ -83,7 +83,7 @@ public class MessageBox {
descriptor.ParentIndex = -1;
descriptor.Parent = (XWindowPeer) UnoRuntime.queryInterface(
XWindowPeer.class,xFrame.getContainerWindow());
descriptor.Bounds = new Rectangle(0,0,300,200);
descriptor.Bounds = new Rectangle(200,100,300,200);
descriptor.WindowAttributes = WindowAttribute.BORDER |
WindowAttribute.MOVEABLE | WindowAttribute.CLOSEABLE;
XWindowPeer xPeer = xToolkit.createWindow(descriptor);

View file

@ -20,7 +20,7 @@
*
* All Rights Reserved.
*
* Version 1.6 (2015-02-10)
* Version 1.6 (2015-02-15)
*
*/
@ -30,25 +30,43 @@ 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.frame.XFrame;
import com.sun.star.lang.IllegalArgumentException;
import com.sun.star.lang.WrappedTargetException;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.text.XDependentTextField;
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.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 writer2latex.office.BibMark;
import writer2latex.office.BibMark.EntryType;
import writer2latex.util.Misc;
/** This class provides a UNO dialog to insert a BibTeX bibliographic reference
*/
@ -85,7 +103,7 @@ public class BibTeXDialog extends DialogBase implements com.sun.star.lang.XIniti
throws com.sun.star.uno.Exception {
for (Object object : objects) {
if (object instanceof XFrame) {
xFrame = (XFrame) UnoRuntime.queryInterface(XFrame.class, object);
xFrame = UnoRuntime.queryInterface(XFrame.class, object);
}
if (object instanceof String) {
bibTeXDirectory = new File((String) object);
@ -113,7 +131,7 @@ public class BibTeXDialog extends DialogBase implements com.sun.star.lang.XIniti
}
@Override public void initialize() {
refresh();
refreshDialog(null);
}
@Override public void endDialog() {
@ -123,22 +141,29 @@ public class BibTeXDialog extends DialogBase implements com.sun.star.lang.XIniti
@Override public boolean callHandlerMethod(XDialog xDialog, Object event, String sMethod) {
if (sMethod.equals("FileChange")) {
// The user has selected another BibTeX file
fileChange();
}
else if (sMethod.equals("EntryChange")) {
// The user has selected another BibTeX entry
entryChange();
}
else if (sMethod.equals("InsertReference")) {
// Insert a reference to the current BibTeX entry
insertReference();
}
else if (sMethod.equals("New")) {
// Create a new BibTeX file
newFile();
}
else if (sMethod.equals("Edit")) {
// Edit the current BibTeX file
edit();
}
else if (sMethod.equals("Refresh")) {
refresh();
// Refresh the dialog and update all bibliographic references
refreshDialog(null);
refreshReferences();
}
return true;
}
@ -151,12 +176,18 @@ public class BibTeXDialog extends DialogBase implements com.sun.star.lang.XIniti
// **** Implement the UI functions
// (Re)load the list of BibTeX files
private void refresh() {
// Remember current file selection, if any
private void refreshDialog(String sSelectedFileName) {
String sFile = null;
short nFile = getListBoxSelectedItem("File");
if (nFile>=0 && files[nFile]!=null) {
sFile = getListBoxStringItemList("File")[nFile];
if (sSelectedFileName!=null) {
// Select a new file name
sFile = sSelectedFileName;
}
else {
// Remember the previous selection, if any
short nSelectedFile = getListBoxSelectedItem("File");
if (nSelectedFile>=0 && files[nSelectedFile]!=null) {
sFile = getListBoxStringItemList("File")[nSelectedFile];
}
}
if (bibTeXDirectory!=null && bibTeXDirectory.isDirectory()) {
@ -170,7 +201,7 @@ public class BibTeXDialog extends DialogBase implements com.sun.star.lang.XIniti
String[] sFileNames = new String[nFileCount];
// Select either the first or the previous item
nFile = 0;
short nFile = 0;
for (short i=0; i<nFileCount; i++) {
sFileNames[i] = files[i].getName();
if (sFileNames[i].equals(sFile)) { nFile = i; }
@ -284,19 +315,60 @@ public class BibTeXDialog extends DialogBase implements com.sun.star.lang.XIniti
// Insert the currently selected entry as a reference in the text document
private void insertReference() {
if (xFrame!=null) {
insertReference(getCurrentEntry());
}
insertReference(getCurrentEntry());
}
// Create a new BibTeX file
private void newFile() {
if (xFrame!=null) {
MessageBox msgBox = new MessageBox(xContext, xFrame);
msgBox.showMessage("Writer2LaTeX","This feature is not implemented yet");
}
String sFileName = getFileName();
if (sFileName!=null) {
File file = new File(bibTeXDirectory,sFileName);
try {
if (!file.createNewFile() && xFrame!=null) {
MessageBox msgBox = new MessageBox(xContext, xFrame);
msgBox.showMessage("Writer2LaTeX","The file "+sFileName+" already exists");
}
refreshDialog(sFileName);
} catch (IOException e) {
}
}
}
// 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]);
String sResult = null;
if (xDialog.execute()==ExecutableDialogResults.OK) {
DialogAccess dlg = new DialogAccess(xDialog);
sResult = dlg.getTextFieldText("Name");
}
xDialog.endExecute();
if (sResult!=null && !sResult.toLowerCase().endsWith(".bib")) {
sResult = sResult+".bib";
}
return Misc.makeTeXFriendly(sResult,"bibliography");
}
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);
XDialogProvider2 xDialogProvider = (XDialogProvider2)
UnoRuntime.queryInterface(XDialogProvider2.class, provider);
String sDialogUrl = "vnd.sun.star.script:"+getDialogLibraryName()+".NewDialog?location=application";
return xDialogProvider.createDialog(sDialogUrl);
}
catch (Exception e) {
return null;
}
}
// Edit the currently selected BibTeX file, if any
private void edit() {
int nFile = getListBoxSelectedItem("File");
@ -320,7 +392,7 @@ public class BibTeXDialog extends DialogBase implements com.sun.star.lang.XIniti
}
// **** Implement core functions
// Edit a BibTeX files using the systems default application, if any
private void edit(File file) {
if (Desktop.isDesktopSupported()) {
@ -340,34 +412,127 @@ public class BibTeXDialog extends DialogBase implements com.sun.star.lang.XIniti
}
}
// Refresh all bibliographic fields in the document
private void refreshReferences() {
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
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) {
String sId = updateTextField(xTextField, readers);
if (sId!=null) {
notUpdated.add(sId);
}
}
}
} catch (NoSuchElementException e) {
} catch (WrappedTargetException e) {
}
}
// Inform the user about the result
if (xFrame!=null) {
MessageBox msgBox = new MessageBox(xContext, xFrame);
if (notUpdated.isEmpty()) {
msgBox.showMessage("Writer2LaTeX","All bibliography fields were updated");
}
else {
msgBox.showMessage("Writer2LaTeX","The following bibliography fields were not updated:\n"+notUpdated.toString());
}
}
}
}
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]);
} catch (IOException e) {
readers[i] = null;
} catch (ParseException e) {
readers[i] = null;
}
}
return readers;
}
// Update a text field, returning the identifier on failure and null on success(!)
private String updateTextField(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) {
} catch (WrappedTargetException e) {
}
}
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 = (XTextDocument) UnoRuntime.queryInterface(
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 = (XTextViewCursorSupplier) UnoRuntime.queryInterface(
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 = (XMultiServiceFactory) UnoRuntime.queryInterface(
XMultiServiceFactory xDocFactory = UnoRuntime.queryInterface(
XMultiServiceFactory.class, xFrame.getController().getModel());
// Use the service factory to create a bibliography field
XDependentTextField xBibField = (XDependentTextField) UnoRuntime.queryInterface (
XDependentTextField xBibField = UnoRuntime.queryInterface (
XDependentTextField.class, xDocFactory.createInstance("com.sun.star.text.textfield.Bibliography"));
// Create a field master for the field
XPropertySet xMasterPropSet = (XPropertySet) UnoRuntime.queryInterface(
XPropertySet xMasterPropSet = UnoRuntime.queryInterface(
XPropertySet.class, xDocFactory.createInstance("com.sun.star.text.fieldmaster.Bibliography"));
// Populate the bibliography field
XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface(
XPropertySet xPropSet = UnoRuntime.queryInterface(
XPropertySet.class, xBibField);
PropertyValue[] fields = createBibliographyFields(bibMark);
xPropSet.setPropertyValue("Fields", fields);
@ -378,7 +543,6 @@ public class BibTeXDialog extends DialogBase implements com.sun.star.lang.XIniti
// Finally, insert the field at the end of the cursor
xText.insertTextContent(xViewCursor.getEnd(), xBibField, false);
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
}
@ -392,7 +556,7 @@ public class BibTeXDialog extends DialogBase implements com.sun.star.lang.XIniti
fields[0].Name="Identifier";
fields[0].Value=bibMark.getIdentifier();
fields[1] = new PropertyValue();
fields[1].Name="BibiliographicType"; // sic!
fields[1].Name="BibiliographicType"; // sic! (API typo)
fields[1].Value=new Short(getBibliographicType(bibMark.getEntryType()));
int i=1;
@ -512,67 +676,8 @@ public class BibTeXDialog extends DialogBase implements com.sun.star.lang.XIniti
return (short)21;
}
else {
return (short)10; // misc
return (short)10; // Use misc for unknown types
}
}
}
// Some test code kept for future reference: Traverse all existing bibliography fields
/* private void test() {
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();
System.out.println("************");
if (AnyConverter.isObject(elm)) {
XTextField xTextField = (XTextField) AnyConverter.toObject(XTextField.class, elm);
if (xTextField!=null) {
XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface(
XPropertySet.class, xTextField);
if (xPropSet!=null) {
try {
Object propsobj = xPropSet.getPropertyValue("Fields");
if (propsobj!=null && propsobj instanceof PropertyValue[]) {
PropertyValue[] props = (PropertyValue[]) propsobj;
for (PropertyValue prop : props) {
if (prop.Value instanceof String) {
System.out.println("String "+prop.Name+"=>"+(String)prop.Value);
}
else if (prop.Value instanceof Short) {
System.out.println("Short "+prop.Name+"=>"+(Short)prop.Value);
}
else {
System.out.println("Other "+prop.Name+"=>"+prop.Value.getClass().getName());
}
}
}
else {
System.out.println("Unexpected type of fields");
}
} catch (UnknownPropertyException e) {
System.out.println("Unknown property?");
}
}
else {
System.out.println("No properties");
}
}
else {
System.out.println("Found something unexpected");
}
}
else {
System.out.println("Found nothing");
}
} catch (NoSuchElementException e) {
e.printStackTrace();
} catch (WrappedTargetException e) {
e.printStackTrace();
}
}
}
*/

View file

@ -16,11 +16,11 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* Copyright: 2002-2014 by Henrik Just
* Copyright: 2002-2015 by Henrik Just
*
* All Rights Reserved.
*
* Version 1.6 (2014-12-27)
* Version 1.6 (2015-02-16)
*
*/
package org.openoffice.da.comp.writer2latex;
@ -77,84 +77,7 @@ public class LaTeXUNOPublisher extends UNOPublisher {
/** Make a file name LaTeX friendly
*/
@Override protected String filterFileName(String sFileName) {
String sResult = "";
for (int i=0; i<sFileName.length(); i++) {
char c = sFileName.charAt(i);
if ((c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9')) {
sResult += Character.toString(c);
}
else {
switch (c) {
case '.': sResult += "."; break;
case '-': sResult += "-"; break;
case ' ' : sResult += "-"; break;
case '_' : sResult += "-"; break;
// Replace accented and national characters
case '\u00c0' : sResult += "A"; break;
case '\u00c1' : sResult += "A"; break;
case '\u00c2' : sResult += "A"; break;
case '\u00c3' : sResult += "A"; break;
case '\u00c4' : sResult += "AE"; break;
case '\u00c5' : sResult += "AA"; break;
case '\u00c6' : sResult += "AE"; break;
case '\u00c7' : sResult += "C"; break;
case '\u00c8' : sResult += "E"; break;
case '\u00c9' : sResult += "E"; break;
case '\u00ca' : sResult += "E"; break;
case '\u00cb' : sResult += "E"; break;
case '\u00cc' : sResult += "I"; break;
case '\u00cd' : sResult += "I"; break;
case '\u00ce' : sResult += "I"; break;
case '\u00cf' : sResult += "I"; break;
case '\u00d0' : sResult += "D"; break;
case '\u00d1' : sResult += "N"; break;
case '\u00d2' : sResult += "O"; break;
case '\u00d3' : sResult += "O"; break;
case '\u00d4' : sResult += "O"; break;
case '\u00d5' : sResult += "O"; break;
case '\u00d6' : sResult += "OE"; break;
case '\u00d8' : sResult += "OE"; break;
case '\u00d9' : sResult += "U"; break;
case '\u00da' : sResult += "U"; break;
case '\u00db' : sResult += "U"; break;
case '\u00dc' : sResult += "UE"; break;
case '\u00dd' : sResult += "Y"; break;
case '\u00df' : sResult += "sz"; break;
case '\u00e0' : sResult += "a"; break;
case '\u00e1' : sResult += "a"; break;
case '\u00e2' : sResult += "a"; break;
case '\u00e3' : sResult += "a"; break;
case '\u00e4' : sResult += "ae"; break;
case '\u00e5' : sResult += "aa"; break;
case '\u00e6' : sResult += "ae"; break;
case '\u00e7' : sResult += "c"; break;
case '\u00e8' : sResult += "e"; break;
case '\u00e9' : sResult += "e"; break;
case '\u00ea' : sResult += "e"; break;
case '\u00eb' : sResult += "e"; break;
case '\u00ec' : sResult += "i"; break;
case '\u00ed' : sResult += "i"; break;
case '\u00ee' : sResult += "i"; break;
case '\u00ef' : sResult += "i"; break;
case '\u00f0' : sResult += "d"; break;
case '\u00f1' : sResult += "n"; break;
case '\u00f2' : sResult += "o"; break;
case '\u00f3' : sResult += "o"; break;
case '\u00f4' : sResult += "o"; break;
case '\u00f5' : sResult += "o"; break;
case '\u00f6' : sResult += "oe"; break;
case '\u00f8' : sResult += "oe"; break;
case '\u00f9' : sResult += "u"; break;
case '\u00fa' : sResult += "u"; break;
case '\u00fb' : sResult += "u"; break;
case '\u00fc' : sResult += "ue"; break;
case '\u00fd' : sResult += "y"; break;
case '\u00ff' : sResult += "y"; break;
}
}
}
if (sResult.length()==0) { return "writer2latex"; }
else { return sResult; }
return Misc.makeTeXFriendly(sFileName,"writer2latex");
}
/** Post process the filter data: Set bibliography options and