From 9f9b9bd7a72dfc9b54f798e52ce2713707bb2857 Mon Sep 17 00:00:00 2001 From: henrikjust Date: Mon, 9 Feb 2015 14:16:34 +0000 Subject: [PATCH] BibTeX support git-svn-id: svn://svn.code.sf.net/p/writer2latex/code/trunk@227 f0f2a975-2e09-46c8-9428-3b39399b9f3c --- source/distro/Readme.txt | 2 +- source/distro/changelog.txt | 2 +- .../da/comp/writer2latex/BibTeXDialog.java | 369 +++++++++++++++--- source/oxt/writer2latex/W4LDialogs/Addons.xcu | 83 ---- source/readme-source.txt | 44 ++- 5 files changed, 356 insertions(+), 144 deletions(-) delete mode 100644 source/oxt/writer2latex/W4LDialogs/Addons.xcu diff --git a/source/distro/Readme.txt b/source/distro/Readme.txt index acac380..bd85948 100644 --- a/source/distro/Readme.txt +++ b/source/distro/Readme.txt @@ -14,5 +14,5 @@ Bugs and feature requests should be reported to writer2latex (at) gmail.com -November 2014 +February 2015 Henrik Just diff --git a/source/distro/changelog.txt b/source/distro/changelog.txt index 0f17524..94f01a5 100644 --- a/source/distro/changelog.txt +++ b/source/distro/changelog.txt @@ -13,7 +13,7 @@ Items marked with * are work in progress [w2x] New boolean option embed_img (default false). If set to true, the binary contents of img elements are included directly on the src attribute as base64. -[w2l] *Added new BibTeX dialog to insert a bibliographic reference to a BibTeX file. The BibTeX files are located as +[w2l] Added new BibTeX dialog to insert a bibliographic reference to a BibTeX file. The BibTeX files are located as defined in the configuration, and the reference is inserted as an ordinary reference mark. [w2l] Various improvements to the log viewer dialog: Reduced height to better accommodate small screen resolutions. diff --git a/source/java/org/openoffice/da/comp/writer2latex/BibTeXDialog.java b/source/java/org/openoffice/da/comp/writer2latex/BibTeXDialog.java index fdf72f7..1dcb8bd 100644 --- a/source/java/org/openoffice/da/comp/writer2latex/BibTeXDialog.java +++ b/source/java/org/openoffice/da/comp/writer2latex/BibTeXDialog.java @@ -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-09) * */ @@ -31,7 +31,15 @@ import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import com.sun.star.awt.XDialog; +import com.sun.star.beans.PropertyValue; +import com.sun.star.beans.XPropertySet; import com.sun.star.frame.XFrame; +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.XTextViewCursor; +import com.sun.star.text.XTextViewCursorSupplier; import com.sun.star.uno.UnoRuntime; import com.sun.star.uno.XComponentContext; @@ -45,20 +53,18 @@ import writer2latex.office.BibMark.EntryType; /** 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 name. + /** The component will be registered under this service name */ public static String __serviceName = "org.openoffice.da.writer2latex.BibTeXDialog"; - /** The component should also have an implementation name. + /** The implementation name of the component */ public static String __implementationName = "org.openoffice.da.comp.writer2latex.BibTeXDialog"; - /** Return the name of the library containing the dialog - */ - public String getDialogLibraryName() { - return "W4LDialogs"; - } + // **** Member variables // The current frame (passed at initialization) XFrame xFrame = null; @@ -72,27 +78,10 @@ public class BibTeXDialog extends DialogBase implements com.sun.star.lang.XIniti // Cache of the current BibTeX file BibTeXReader currentFile = null; - /** Return the name of the dialog within the library - */ - public String getDialogName() { - return "BibTeXEntry"; - } - - public void initialize() { - refresh(); - } - - public void endDialog() { - } - - /** Create a new BibTeXDialog */ - public BibTeXDialog(XComponentContext xContext) { - super(xContext); - } - - // Implement com.sun.star.lang.XInitialization + // **** 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 ) + @Override public void initialize( Object[] objects ) throws com.sun.star.uno.Exception { for (Object object : objects) { if (object instanceof XFrame) { @@ -103,9 +92,36 @@ public class BibTeXDialog extends DialogBase implements com.sun.star.lang.XIniti } } } + + // **** Extend DialogBase + + /** Create a new BibTeXDialog */ + public BibTeXDialog(XComponentContext xContext) { + super(xContext); + } + + /** Return the name of the library containing the dialog + */ + @Override public String getDialogLibraryName() { + return "W4LDialogs"; + } + + /** Return the name of the dialog within the library + */ + @Override public String getDialogName() { + return "BibTeXEntry"; + } + + @Override public void initialize() { + refresh(); + } + + @Override public void endDialog() { + } - // Implement XDialogEventHandler - public boolean callHandlerMethod(XDialog xDialog, Object event, String sMethod) { + // **** Implement XDialogEventHandler + + @Override public boolean callHandlerMethod(XDialog xDialog, Object event, String sMethod) { if (sMethod.equals("FileChange")) { fileChange(); } @@ -124,11 +140,13 @@ public class BibTeXDialog extends DialogBase implements com.sun.star.lang.XIniti return true; } - public String[] getSupportedMethodNames() { + @Override public String[] getSupportedMethodNames() { String[] sNames = { "FileChange", "EntryChange", "InsertReference", "Edit", "Refresh" }; return sNames; } + // **** Implement the UI functions + // (Re)load the list of BibTeX files private void refresh() { // Remember current file selection, if any @@ -264,12 +282,21 @@ 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) { - MessageBox msgBox = new MessageBox(xContext, xFrame); - msgBox.showMessage("Writer2LaTeX","This feature has not been implemented yet"); + insertReference(getCurrentEntry()); } } - // Get the currently selected entry, or null if none is selected + // Edit the currently selected BibTeX file, if any + private void edit() { + int nFile = getListBoxSelectedItem("File"); + 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"); @@ -281,26 +308,260 @@ public class BibTeXDialog extends DialogBase implements com.sun.star.lang.XIniti return bibMark; } - // Edit the current BibTeX file - private void edit() { - int nFile = getListBoxSelectedItem("File"); - if (nFile>=0) { - if (files[nFile].exists()) { - // Open the file in the default application on this system (if any) - if (Desktop.isDesktopSupported()) { - Desktop desktop = Desktop.getDesktop(); - try { - desktop.open(files[nFile]); - } catch (IOException e) { - System.err.println(e.getMessage()); - } - } - else if (xFrame!=null) { + // **** 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","Error: No BibTeX editor was found"); - } - } + msgBox.showMessage("Writer2LaTeX","Error: Failed to open file with BibTeX editor"); + } + } + } + else if (xFrame!=null) { + MessageBox msgBox = new MessageBox(xContext, xFrame); + msgBox.showMessage("Writer2LaTeX","Error: No BibTeX editor was found"); + } + } + + // 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.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.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.class, xFrame.getController().getModel()); + + // Use the service factory to create a bibliography field + XDependentTextField xBibField = (XDependentTextField) 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.class, xDocFactory.createInstance("com.sun.star.text.fieldmaster.Bibliography")); + + // Populate the bibliography field + XPropertySet xPropSet = (XPropertySet) 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) { + e.printStackTrace(System.out); + } } } -} \ No newline at end of file + // 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! + 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; // misc + } + } + +} + +// 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(); + } + } +} +*/ \ No newline at end of file diff --git a/source/oxt/writer2latex/W4LDialogs/Addons.xcu b/source/oxt/writer2latex/W4LDialogs/Addons.xcu deleted file mode 100644 index 32ac902..0000000 --- a/source/oxt/writer2latex/W4LDialogs/Addons.xcu +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - - - - com.sun.star.text.TextDocument - - - Insert BibTeX citation - Indsæt BibTeX-reference - - - _self - - - org.openoffice.da.writer2latex:InsertBibTeX - - - %origin%/icons/bibtex - - - - - com.sun.star.text.TextDocument - - - Publish to LaTeX - Publicer til LaTeX - - - _self - - - org.openoffice.da.writer2latex:ProcessDocument - - - %origin%/icons/latex - - - - - com.sun.star.text.TextDocument - - - View log files - Vis logfiler - - - _self - - - org.openoffice.da.writer2latex:ViewLog - - - %origin%/icons/log - - - - - com.sun.star.text.TextDocument - - - Edit custom format - Rediger brugerdefineret format - - - _self - - - .uno:OptionsTreeDialog?OptionsPageURL:string=%origin%/W2LDialogs2/Documentclass.xdl - - - %origin%/icons/custom - - - - - - - \ No newline at end of file diff --git a/source/readme-source.txt b/source/readme-source.txt index adacd29..25af01b 100644 --- a/source/readme-source.txt +++ b/source/readme-source.txt @@ -1,7 +1,7 @@ Writer2LaTeX source version 1.5.2 alpha ======================================= -Writer2LaTeX is (c) 2002-2014 by Henrik Just. +Writer2LaTeX is (c) 2002-2015 by Henrik Just. The source is available under the terms and conditions of the GNU LESSER GENERAL PUBLIC LICENSE, version 2.1. Please see the file COPYING.TXT for details. @@ -24,10 +24,12 @@ Currently parts of the source for Writer2LaTeX are somewhat messy and undocumented. This situation tends to improve over time :-) -Third-party software --------------------- +Third-party software: JSON.org +------------------------------ + +The JSON library org.json.* from JSON.org is included in binary form as json-20140107.jar. +The source code is available from JSON.org. -The classes org.json.* from JSON.org are included as json-20140107.jar. The source code is available from JSON.org. Copyright notice: The classes org.json.* are copyright (c) 2002 JSON.org and is used subject to the following notice @@ -47,6 +49,38 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRA CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +Third-party software: +--------------------------- + +Villu Ruusmanns Java BibTeX API is included in binary form as jbibtex-1.0.14.jar. +The source code is available from https://code.google.com/p/java-bibtex/ + +Copyright notice: + +Copyright (c) 2012, University of Tartu +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that +the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the +following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +following disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Building Writer2LaTeX --------------------- @@ -90,7 +124,7 @@ In addition to oxt, the build file supports the following targets: clean -Henrik Just, November 2014 +Henrik Just, February 2015 Thanks to Michael Niedermair for writing the original ant build file