Extended config API + More config ui work
git-svn-id: svn://svn.code.sf.net/p/writer2latex/code/trunk@38 f0f2a975-2e09-46c8-9428-3b39399b9f3c
This commit is contained in:
parent
52694ed9c9
commit
cc1fcbb4f9
6 changed files with 264 additions and 139 deletions
|
@ -20,7 +20,7 @@
|
||||||
*
|
*
|
||||||
* All Rights Reserved.
|
* All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Version 1.2 (2009-09-23)
|
* Version 1.2 (2009-09-27)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -29,6 +29,8 @@ package org.openoffice.da.comp.writer2latex;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.text.Collator;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -828,6 +830,7 @@ public final class ConfigurationDialog extends WeakBase
|
||||||
for (String s : symbolnames) {
|
for (String s : symbolnames) {
|
||||||
sSymbolNames[i++] = s;
|
sSymbolNames[i++] = s;
|
||||||
}
|
}
|
||||||
|
sortStringArray(sSymbolNames);
|
||||||
dlg.setListBoxStringItemList("MathSymbolName", sSymbolNames);
|
dlg.setListBoxStringItemList("MathSymbolName", sSymbolNames);
|
||||||
dlg.setListBoxSelectedItem("MathSymbolName", (short)0);
|
dlg.setListBoxSelectedItem("MathSymbolName", (short)0);
|
||||||
sCurrentMathSymbol = sSymbolNames[0];
|
sCurrentMathSymbol = sSymbolNames[0];
|
||||||
|
@ -838,6 +841,7 @@ public final class ConfigurationDialog extends WeakBase
|
||||||
for (String s : names) {
|
for (String s : names) {
|
||||||
sNames[j++] = s;
|
sNames[j++] = s;
|
||||||
}
|
}
|
||||||
|
sortStringArray(sNames);
|
||||||
dlg.setListBoxStringItemList("TextInput", sNames);
|
dlg.setListBoxStringItemList("TextInput", sNames);
|
||||||
dlg.setListBoxSelectedItem("TextInput", (short)0);
|
dlg.setListBoxSelectedItem("TextInput", (short)0);
|
||||||
sCurrentText = sNames[0];
|
sCurrentText = sNames[0];
|
||||||
|
@ -905,5 +909,12 @@ public final class ConfigurationDialog extends WeakBase
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Utilities
|
||||||
|
private void sortStringArray(String[] theArray) {
|
||||||
|
// TODO: Get locale from OOo rather than the system
|
||||||
|
Collator collator = Collator.getInstance();
|
||||||
|
Arrays.sort(theArray, collator);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
*
|
*
|
||||||
* All Rights Reserved.
|
* All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Version 1.2 (2009-09-17)
|
* Version 1.2 (2009-09-28)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ public class ConverterFactory {
|
||||||
|
|
||||||
// Version information
|
// Version information
|
||||||
private static final String VERSION = "1.1.1";
|
private static final String VERSION = "1.1.1";
|
||||||
private static final String DATE = "2008-09-17";
|
private static final String DATE = "2009-09-28";
|
||||||
|
|
||||||
/** Return version information
|
/** Return version information
|
||||||
* @return the Writer2LaTeX version in the form
|
* @return the Writer2LaTeX version in the form
|
||||||
|
|
|
@ -20,14 +20,13 @@
|
||||||
*
|
*
|
||||||
* All Rights Reserved.
|
* All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Version 1.2 (2009-09-24)
|
* Version 1.2 (2009-09-28)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package writer2latex.latex;
|
package writer2latex.latex;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
@ -46,12 +45,17 @@ import writer2latex.latex.util.StyleMap;
|
||||||
import writer2latex.util.Misc;
|
import writer2latex.util.Misc;
|
||||||
|
|
||||||
public class LaTeXConfig extends writer2latex.base.ConfigBase {
|
public class LaTeXConfig extends writer2latex.base.ConfigBase {
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
// I. Define items needed by ConfigBase
|
||||||
|
|
||||||
protected int getOptionCount() { return 63; }
|
protected int getOptionCount() { return 63; }
|
||||||
protected String getDefaultConfigPath() { return "/writer2latex/latex/config/"; }
|
protected String getDefaultConfigPath() { return "/writer2latex/latex/config/"; }
|
||||||
|
|
||||||
// Override getter and setter methods for options in order to:
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
// II. Override getter and setter methods for simple options in order to:
|
||||||
// - Treat the custom preamble like a regular option, even though the xml representation is different
|
// - Treat the custom preamble like a regular option, even though the xml representation is different
|
||||||
// - Be backwards compatible (renamed option)
|
// - Be backwards compatible (renamed the option keep_image_size)
|
||||||
|
|
||||||
@Override public void setOption(String sName,String sValue) {
|
@Override public void setOption(String sName,String sValue) {
|
||||||
if (sName.equals("custom-preamble")) {
|
if (sName.equals("custom-preamble")) {
|
||||||
sCustomPreamble = sValue;
|
sCustomPreamble = sValue;
|
||||||
|
@ -72,6 +76,9 @@ public class LaTeXConfig extends writer2latex.base.ConfigBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
// III. Declare all constants
|
||||||
|
|
||||||
// Backend
|
// Backend
|
||||||
public static final int GENERIC = 0;
|
public static final int GENERIC = 0;
|
||||||
public static final int DVIPS = 1;
|
public static final int DVIPS = 1;
|
||||||
|
@ -103,8 +110,6 @@ public class LaTeXConfig extends writer2latex.base.ConfigBase {
|
||||||
public static final int CUSTOM = 4;
|
public static final int CUSTOM = 4;
|
||||||
|
|
||||||
// Options
|
// Options
|
||||||
protected int OPTION_COUNT = 63;
|
|
||||||
|
|
||||||
private static final int BACKEND = 0;
|
private static final int BACKEND = 0;
|
||||||
private static final int NO_PREAMBLE = 1;
|
private static final int NO_PREAMBLE = 1;
|
||||||
private static final int NO_INDEX = 2;
|
private static final int NO_INDEX = 2;
|
||||||
|
@ -168,21 +173,29 @@ public class LaTeXConfig extends writer2latex.base.ConfigBase {
|
||||||
private static final int SPLIT_TOPLEVEL_SECTIONS = 60;
|
private static final int SPLIT_TOPLEVEL_SECTIONS = 60;
|
||||||
private static final int SAVE_IMAGES_IN_SUBDIR = 61;
|
private static final int SAVE_IMAGES_IN_SUBDIR = 61;
|
||||||
private static final int DEBUG = 62;
|
private static final int DEBUG = 62;
|
||||||
|
|
||||||
protected String sCustomPreamble = "";
|
|
||||||
protected StyleMap par = new StyleMap();
|
|
||||||
protected StyleMap parBlock = new StyleMap();
|
|
||||||
protected StyleMap text = new StyleMap();
|
|
||||||
protected StyleMap list = new StyleMap();
|
|
||||||
protected StyleMap listItem = new StyleMap();
|
|
||||||
protected StyleMap textAttr = new StyleMap();
|
|
||||||
protected HeadingMap headingMap = new HeadingMap(5);
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
// IV. Our options data
|
||||||
|
|
||||||
|
private ComplexOption headingMap;
|
||||||
|
private ComplexOption parMap;
|
||||||
|
private ComplexOption parBlockMap;
|
||||||
|
private ComplexOption listMap;
|
||||||
|
private ComplexOption listItemMap;
|
||||||
|
private ComplexOption textMap;
|
||||||
|
private ComplexOption textAttrMap;
|
||||||
private ComplexOption stringReplace;
|
private ComplexOption stringReplace;
|
||||||
private ComplexOption mathSymbols;
|
private ComplexOption mathSymbols;
|
||||||
|
private String sCustomPreamble = "";
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
// V. The rather long constructor setting all defaults
|
||||||
|
|
||||||
|
/** Construct a new <code>LaTeXConfig</code> with default values for all options
|
||||||
|
*/
|
||||||
public LaTeXConfig() {
|
public LaTeXConfig() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
// create options with default values
|
// create options with default values
|
||||||
options[NO_PREAMBLE] = new BooleanOption("no_preamble","false");
|
options[NO_PREAMBLE] = new BooleanOption("no_preamble","false");
|
||||||
options[NO_INDEX] = new BooleanOption("no_index","false");
|
options[NO_INDEX] = new BooleanOption("no_index","false");
|
||||||
|
@ -297,19 +310,49 @@ public class LaTeXConfig extends writer2latex.base.ConfigBase {
|
||||||
options[SPLIT_TOPLEVEL_SECTIONS] = new BooleanOption("split_toplevel_sections","false");
|
options[SPLIT_TOPLEVEL_SECTIONS] = new BooleanOption("split_toplevel_sections","false");
|
||||||
options[SAVE_IMAGES_IN_SUBDIR] = new BooleanOption("save_images_in_subdir","false");
|
options[SAVE_IMAGES_IN_SUBDIR] = new BooleanOption("save_images_in_subdir","false");
|
||||||
options[DEBUG] = new BooleanOption("debug","false");
|
options[DEBUG] = new BooleanOption("debug","false");
|
||||||
// Headings for article class:
|
|
||||||
headingMap.setLevelData(1,"section",1);
|
// Complex options - heading map
|
||||||
headingMap.setLevelData(2,"subsection",2);
|
headingMap = addComplexOption("heading-map");
|
||||||
headingMap.setLevelData(3,"subsubsection",3);
|
Map<String,String> attr = new HashMap<String,String>();
|
||||||
headingMap.setLevelData(4,"paragraph",4);
|
attr.put("name", "section");
|
||||||
headingMap.setLevelData(5,"subparagraph",5);
|
attr.put("level", "1");
|
||||||
|
headingMap.put("1", attr);
|
||||||
|
|
||||||
// Complex options
|
attr = new HashMap<String,String>();
|
||||||
|
attr.put("name", "subsection");
|
||||||
|
attr.put("level", "2");
|
||||||
|
headingMap.put("2", attr);
|
||||||
|
|
||||||
|
attr = new HashMap<String,String>();
|
||||||
|
attr.put("name", "subsubsection");
|
||||||
|
attr.put("level", "3");
|
||||||
|
headingMap.put("3", attr);
|
||||||
|
|
||||||
|
attr = new HashMap<String,String>();
|
||||||
|
attr.put("name", "paragraph");
|
||||||
|
attr.put("level", "4");
|
||||||
|
headingMap.put("4", attr);
|
||||||
|
|
||||||
|
attr = new HashMap<String,String>();
|
||||||
|
attr.put("name", "subparagraph");
|
||||||
|
attr.put("level", "5");
|
||||||
|
headingMap.put("5", attr);
|
||||||
|
|
||||||
|
// Complex options - style maps
|
||||||
|
parMap = addComplexOption("paragraph-map");
|
||||||
|
parBlockMap = addComplexOption("paragraph-block-map");
|
||||||
|
listMap = addComplexOption("list-map");
|
||||||
|
listItemMap = addComplexOption("list-item-map");
|
||||||
|
textMap = addComplexOption("text-map");
|
||||||
|
textAttrMap = addComplexOption("text-attribute-map");
|
||||||
|
|
||||||
|
// Complex options - string replace
|
||||||
stringReplace=addComplexOption("string-replace");
|
stringReplace=addComplexOption("string-replace");
|
||||||
|
|
||||||
// Standard string replace:
|
// Standard string replace:
|
||||||
// Fix french spacing; replace nonbreaking space
|
// Fix french spacing; replace nonbreaking space
|
||||||
// right before em-dash, !, ?, : and ; (babel handles this)
|
// right before em-dash, !, ?, : and ; (babel handles this)
|
||||||
Map<String,String> attr = new HashMap<String,String>();
|
attr = new HashMap<String,String>();
|
||||||
attr.put("fontenc", "any");
|
attr.put("fontenc", "any");
|
||||||
attr.put("latex-code", " \u2014");
|
attr.put("latex-code", " \u2014");
|
||||||
stringReplace.put("\u00A0\u2014",attr);
|
stringReplace.put("\u00A0\u2014",attr);
|
||||||
|
@ -340,51 +383,81 @@ public class LaTeXConfig extends writer2latex.base.ConfigBase {
|
||||||
//stringReplace.put("\u00AB\u00A0","\u00AB ",I18n.readFontencs("any"));
|
//stringReplace.put("\u00AB\u00A0","\u00AB ",I18n.readFontencs("any"));
|
||||||
//stringReplace.put("\u00A0\u00BB"," \u00BB",I18n.readFontencs("any"));
|
//stringReplace.put("\u00A0\u00BB"," \u00BB",I18n.readFontencs("any"));
|
||||||
|
|
||||||
|
// Complex options - math user defined symbols
|
||||||
mathSymbols = addComplexOption("math-symbol-map");
|
mathSymbols = addComplexOption("math-symbol-map");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// VI. Provide methods to fill in the gaps in the supers read and write methods
|
||||||
|
|
||||||
protected void readInner(Element elm) {
|
protected void readInner(Element elm) {
|
||||||
if (elm.getTagName().equals("style-map")) {
|
if (elm.getTagName().equals("heading-map")) {
|
||||||
|
// Unlike other complex options, a heading map is completely replaced
|
||||||
|
headingMap.clear();
|
||||||
|
Node child = elm.getFirstChild();
|
||||||
|
while (child!=null) {
|
||||||
|
if (child.getNodeType()==Node.ELEMENT_NODE) {
|
||||||
|
Element childElm = (Element) child;
|
||||||
|
if (childElm.getTagName().equals("heading-level-map")) {
|
||||||
|
if (childElm.hasAttribute("writer-level")) {
|
||||||
|
Map<String,String> attr = new HashMap<String,String>();
|
||||||
|
attr.put("name",childElm.getAttribute("name"));
|
||||||
|
attr.put("level",childElm.getAttribute("level"));
|
||||||
|
headingMap.put(childElm.getAttribute("writer-level"), attr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
child = child.getNextSibling();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (elm.getTagName().equals("style-map")) {
|
||||||
String sName = elm.getAttribute("name");
|
String sName = elm.getAttribute("name");
|
||||||
String sFamily = elm.getAttribute("family");
|
String sFamily = elm.getAttribute("family");
|
||||||
if (sFamily.length()==0) { // try old name
|
if (sFamily.length()==0) { // try old name
|
||||||
sFamily = elm.getAttribute("class");
|
sFamily = elm.getAttribute("class");
|
||||||
}
|
}
|
||||||
String sBefore = elm.getAttribute("before");
|
|
||||||
String sAfter = elm.getAttribute("after");
|
Map<String,String> attr = new HashMap<String,String>();
|
||||||
boolean bLineBreak = !"false".equals(elm.getAttribute("line-break"));
|
attr.put("before", elm.getAttribute("before"));
|
||||||
boolean bVerbatim = "true".equals(elm.getAttribute("verbatim"));
|
attr.put("after", elm.getAttribute("after"));
|
||||||
|
|
||||||
if ("paragraph".equals(sFamily)) {
|
if ("paragraph".equals(sFamily)) {
|
||||||
par.put(sName,sBefore,sAfter,bLineBreak,bVerbatim);
|
if (elm.hasAttribute("line-break")) { attr.put("line-break", elm.getAttribute("line-break")); }
|
||||||
|
if (elm.hasAttribute("verbatim")) { attr.put("verbatim", elm.getAttribute("verbatim")); }
|
||||||
|
parMap.put(sName, attr);
|
||||||
}
|
}
|
||||||
if ("paragraph-block".equals(sFamily)) {
|
if ("paragraph-block".equals(sFamily)) {
|
||||||
String sNext = elm.getAttribute("next");
|
attr.put("next", elm.getAttribute("next"));
|
||||||
parBlock.put(sName,sBefore,sAfter,sNext,bVerbatim);
|
if (elm.hasAttribute("verbatim")) { attr.put("verbatim", elm.getAttribute("verbatim")); }
|
||||||
}
|
parBlockMap.put(sName, attr);
|
||||||
else if ("text".equals(sFamily)) {
|
|
||||||
text.put(sName,sBefore,sAfter,false,bVerbatim);
|
|
||||||
}
|
}
|
||||||
else if ("list".equals(sFamily)) {
|
else if ("list".equals(sFamily)) {
|
||||||
list.put(sName,sBefore,sAfter);
|
listMap.put(sName, attr);
|
||||||
}
|
}
|
||||||
else if ("listitem".equals(sFamily)) {
|
else if ("listitem".equals(sFamily)) {
|
||||||
listItem.put(sName,sBefore,sAfter);
|
listItemMap.put(sName, attr);
|
||||||
|
}
|
||||||
|
else if ("text".equals(sFamily)) {
|
||||||
|
if (elm.hasAttribute("verbatim")) { attr.put("verbatim", elm.getAttribute("verbatim")); }
|
||||||
|
textMap.put(sName, attr);
|
||||||
}
|
}
|
||||||
else if ("text-attribute".equals(sFamily)) {
|
else if ("text-attribute".equals(sFamily)) {
|
||||||
textAttr.put(sName, sBefore, sAfter);
|
textAttrMap.put(sName, attr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (elm.getTagName().equals("heading-map")) {
|
|
||||||
readHeadingMap(elm);
|
|
||||||
}
|
|
||||||
else if (elm.getTagName().equals("string-replace")) {
|
else if (elm.getTagName().equals("string-replace")) {
|
||||||
// TODO: ConfigBase should handle this
|
|
||||||
String sInput = elm.getAttribute("input");
|
String sInput = elm.getAttribute("input");
|
||||||
Map<String,String> attributes = new HashMap<String,String>();
|
Map<String,String> attributes = new HashMap<String,String>();
|
||||||
attributes.put("latex-code", elm.getAttribute("latex-code"));
|
attributes.put("latex-code", elm.getAttribute("latex-code"));
|
||||||
attributes.put("fontenc", elm.getAttribute("fontenc"));
|
attributes.put("fontenc", elm.getAttribute("fontenc"));
|
||||||
stringReplace.put(sInput,attributes);
|
stringReplace.put(sInput,attributes);
|
||||||
}
|
}
|
||||||
|
else if (elm.getTagName().equals("math-symbol-map")) {
|
||||||
|
String sName = elm.getAttribute("name");
|
||||||
|
Map<String,String> attr = new HashMap<String,String>();
|
||||||
|
attr.put("latex", elm.getAttribute("latex"));
|
||||||
|
mathSymbols.put(sName, attr);
|
||||||
|
}
|
||||||
else if (elm.getTagName().equals("custom-preamble")) {
|
else if (elm.getTagName().equals("custom-preamble")) {
|
||||||
StringBuffer buf = new StringBuffer();
|
StringBuffer buf = new StringBuffer();
|
||||||
Node child = elm.getFirstChild();
|
Node child = elm.getFirstChild();
|
||||||
|
@ -396,61 +469,36 @@ public class LaTeXConfig extends writer2latex.base.ConfigBase {
|
||||||
}
|
}
|
||||||
sCustomPreamble = buf.toString();
|
sCustomPreamble = buf.toString();
|
||||||
}
|
}
|
||||||
else if (elm.getTagName().equals("math-symbol-map")) {
|
|
||||||
String sName = elm.getAttribute("name");
|
|
||||||
Map<String,String> attr = new HashMap<String,String>();
|
|
||||||
attr.put("latex", elm.getAttribute("latex"));
|
|
||||||
mathSymbols.put(sName, attr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void readHeadingMap(Element node) {
|
|
||||||
int nMaxLevel = Misc.getPosInteger(node.getAttribute("max-level"),0);
|
|
||||||
headingMap.reset(nMaxLevel);
|
|
||||||
Node child = node.getFirstChild();
|
|
||||||
while (child!=null) {
|
|
||||||
if (child.getNodeType()==Node.ELEMENT_NODE) {
|
|
||||||
Element elm = (Element) child;
|
|
||||||
if (elm.getTagName().equals("heading-level-map")) {
|
|
||||||
int nWriterLevel = Misc.getPosInteger(elm.getAttribute("writer-level"),1);
|
|
||||||
String sName = elm.getAttribute("name");
|
|
||||||
int nLevel = Misc.getPosInteger(elm.getAttribute("level"),0);
|
|
||||||
headingMap.setLevelData(nWriterLevel,sName,nLevel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
child = child.getNextSibling();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void writeInner(Document dom) {
|
protected void writeInner(Document dom) {
|
||||||
// Write math symbol map
|
// Write heading map
|
||||||
for (String sName : mathSymbols.keySet()) {
|
int nMaxLevel = 0;
|
||||||
String sLatex = mathSymbols.get(sName).get("latex");
|
while (nMaxLevel<10 && headingMap.get(Integer.toString(nMaxLevel+1))!=null) { nMaxLevel++; }
|
||||||
Element msNode = dom.createElement("math-symbol-map");
|
|
||||||
msNode.setAttribute("name",sName);
|
|
||||||
msNode.setAttribute("latex",sLatex);
|
|
||||||
dom.getDocumentElement().appendChild(msNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
writeStyleMap(dom,par,"paragraph");
|
|
||||||
writeStyleMap(dom,parBlock,"paragraph-block");
|
|
||||||
writeStyleMap(dom,text,"text");
|
|
||||||
writeStyleMap(dom,list,"list");
|
|
||||||
writeStyleMap(dom,listItem,"listitem");
|
|
||||||
writeStyleMap(dom,textAttr,"text-attribute");
|
|
||||||
|
|
||||||
Element hmNode = dom.createElement("heading-map");
|
Element hmNode = dom.createElement("heading-map");
|
||||||
hmNode.setAttribute("max-level",Integer.toString(headingMap.getMaxLevel()));
|
// This attribute is not used anymore, but we keep it for backwards compatibility
|
||||||
|
hmNode.setAttribute("max-level",Integer.toString(nMaxLevel));
|
||||||
dom.getDocumentElement().appendChild(hmNode);
|
dom.getDocumentElement().appendChild(hmNode);
|
||||||
for (int i=1; i<=headingMap.getMaxLevel(); i++) {
|
for (int i=1; i<=nMaxLevel; i++) {
|
||||||
Element hlmNode = dom.createElement("heading-level-map");
|
Element hlmNode = dom.createElement("heading-level-map");
|
||||||
hlmNode.setAttribute("writer-level",Integer.toString(i));
|
String sWriterLevel = Integer.toString(i);
|
||||||
hlmNode.setAttribute("name",headingMap.getName(i));
|
hlmNode.setAttribute("writer-level",sWriterLevel);
|
||||||
hlmNode.setAttribute("level",Integer.toString(headingMap.getLevel(i)));
|
Map<String,String> attr = headingMap.get(sWriterLevel);
|
||||||
|
hlmNode.setAttribute("name",attr.get("name"));
|
||||||
|
hlmNode.setAttribute("level",attr.get("level"));
|
||||||
hmNode.appendChild(hlmNode);
|
hmNode.appendChild(hlmNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: ConfigBase should handle this
|
// Write style maps
|
||||||
|
writeStyleMap(dom,parMap,"paragraph");
|
||||||
|
writeStyleMap(dom,parBlockMap,"paragraph-block");
|
||||||
|
writeStyleMap(dom,listMap,"list");
|
||||||
|
writeStyleMap(dom,listItemMap,"listitem");
|
||||||
|
writeStyleMap(dom,textMap,"text");
|
||||||
|
writeStyleMap(dom,textAttrMap,"text-attribute");
|
||||||
|
|
||||||
|
// Write string replace
|
||||||
Set<String> inputStrings = stringReplace.keySet();
|
Set<String> inputStrings = stringReplace.keySet();
|
||||||
for (String sInput : inputStrings) {
|
for (String sInput : inputStrings) {
|
||||||
Map<String,String> attributes = stringReplace.get(sInput);
|
Map<String,String> attributes = stringReplace.get(sInput);
|
||||||
|
@ -461,34 +509,82 @@ public class LaTeXConfig extends writer2latex.base.ConfigBase {
|
||||||
dom.getDocumentElement().appendChild(srNode);
|
dom.getDocumentElement().appendChild(srNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
Element cp = dom.createElement("custom-preamble");
|
// Write math symbol map
|
||||||
|
for (String sName : mathSymbols.keySet()) {
|
||||||
|
String sLatex = mathSymbols.get(sName).get("latex");
|
||||||
|
Element msNode = dom.createElement("math-symbol-map");
|
||||||
|
msNode.setAttribute("name",sName);
|
||||||
|
msNode.setAttribute("latex",sLatex);
|
||||||
|
dom.getDocumentElement().appendChild(msNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write custom preamble
|
||||||
|
Element cp = dom.createElement("custom-preamble");
|
||||||
cp.appendChild(dom.createTextNode( sCustomPreamble));
|
cp.appendChild(dom.createTextNode( sCustomPreamble));
|
||||||
dom.getDocumentElement().appendChild(cp);
|
dom.getDocumentElement().appendChild(cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeStyleMap(Document dom, StyleMap sm, String sFamily) {
|
private void writeStyleMap(Document dom, ComplexOption co, String sFamily) {
|
||||||
Enumeration<String> smEnum = sm.getNames();
|
for (String sName : co.keySet()) {
|
||||||
while (smEnum.hasMoreElements()) {
|
Map<String,String> attr = co.get(sName);
|
||||||
String sName = smEnum.nextElement();
|
|
||||||
Element smNode = dom.createElement("style-map");
|
Element smNode = dom.createElement("style-map");
|
||||||
smNode.setAttribute("name",sName);
|
smNode.setAttribute("name",sName);
|
||||||
smNode.setAttribute("family",sFamily);
|
smNode.setAttribute("family",sFamily);
|
||||||
smNode.setAttribute("before",sm.getBefore(sName));
|
smNode.setAttribute("before",attr.containsKey("before") ? attr.get("before") : "");
|
||||||
smNode.setAttribute("after",sm.getAfter(sName));
|
smNode.setAttribute("after",attr.containsKey("after") ? attr.get("after") : "");
|
||||||
if (sm.getNext(sName)!=null) {
|
if (attr.containsKey("next")) {
|
||||||
smNode.setAttribute("next",sm.getNext(sName));
|
smNode.setAttribute("next",attr.get("next"));
|
||||||
}
|
}
|
||||||
if (!sm.getLineBreak(sName)) {
|
if (attr.containsKey("line-break")) {
|
||||||
smNode.setAttribute("line-break","false");
|
smNode.setAttribute("line-break",attr.get("line-break"));
|
||||||
}
|
}
|
||||||
if (sm.getVerbatim(sName)) {
|
if (attr.containsKey("verbatim")) {
|
||||||
smNode.setAttribute("verbatim","true");
|
smNode.setAttribute("verbatim",attr.get("verbatim"));
|
||||||
}
|
}
|
||||||
dom.getDocumentElement().appendChild(smNode);
|
dom.getDocumentElement().appendChild(smNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convenience accessor methods
|
/////////////////////////////////////////////////////////////////////////
|
||||||
|
// VII. Convenience accessor methods
|
||||||
|
|
||||||
|
public HeadingMap getHeadingMap() {
|
||||||
|
int nMaxLevel = 0;
|
||||||
|
while (nMaxLevel<10 && headingMap.get(Integer.toString(nMaxLevel+1))!=null) { nMaxLevel++; }
|
||||||
|
|
||||||
|
HeadingMap map = new HeadingMap(nMaxLevel);
|
||||||
|
for (int i=1; i<=nMaxLevel; i++) {
|
||||||
|
String sWriterLevel = Integer.toString(i);
|
||||||
|
Map<String,String> attr = headingMap.get(sWriterLevel);
|
||||||
|
String sName = attr.get("name");
|
||||||
|
int nLevel = Misc.getPosInteger(attr.get("level"),0);
|
||||||
|
map.setLevelData(i, sName, nLevel);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get style maps
|
||||||
|
public StyleMap getParStyleMap() { return getStyleMap(parMap); }
|
||||||
|
public StyleMap getParBlockStyleMap() { return getStyleMap(parBlockMap); }
|
||||||
|
public StyleMap getListStyleMap() { return getStyleMap(listMap); }
|
||||||
|
public StyleMap getListItemStyleMap() { return getStyleMap(listItemMap); }
|
||||||
|
public StyleMap getTextAttributeStyleMap() { return getStyleMap(textAttrMap); }
|
||||||
|
public StyleMap getTextStyleMap() { return getStyleMap(textMap); }
|
||||||
|
|
||||||
|
private StyleMap getStyleMap(ComplexOption co) {
|
||||||
|
StyleMap map = new StyleMap();
|
||||||
|
for (String sName : co.keySet()) {
|
||||||
|
Map<String,String> attr = co.get(sName);
|
||||||
|
String sBefore = attr.containsKey("before") ? attr.get("before") : "";
|
||||||
|
String sAfter = attr.containsKey("after") ? attr.get("after") : "";
|
||||||
|
String sNext = attr.containsKey("next") ? attr.get("next") : "";
|
||||||
|
boolean bLineBreak = !"false".equals(attr.get("line-break"));
|
||||||
|
boolean bVerbatim = "true".equals(attr.get("verbatim"));
|
||||||
|
map.put(sName, sBefore, sAfter, sNext, bLineBreak, bVerbatim);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Return current string replace as a trie
|
// Return current string replace as a trie
|
||||||
public ReplacementTrie getStringReplace() {
|
public ReplacementTrie getStringReplace() {
|
||||||
|
@ -503,6 +599,17 @@ public class LaTeXConfig extends writer2latex.base.ConfigBase {
|
||||||
return trie;
|
return trie;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the math symbols as a simple Map
|
||||||
|
public Map<String, String> getMathSymbols() {
|
||||||
|
Map<String,String> map = new HashMap<String,String>();
|
||||||
|
for (String sName : mathSymbols.keySet()) {
|
||||||
|
String sLatex = mathSymbols.get(sName).get("latex");
|
||||||
|
map.put(sName, sLatex);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the custom preamble
|
||||||
public String getCustomPreamble() { return sCustomPreamble; }
|
public String getCustomPreamble() { return sCustomPreamble; }
|
||||||
|
|
||||||
// Common options
|
// Common options
|
||||||
|
@ -589,22 +696,5 @@ public class LaTeXConfig extends writer2latex.base.ConfigBase {
|
||||||
public boolean splitToplevelSections() { return ((BooleanOption) options[SPLIT_TOPLEVEL_SECTIONS]).getValue(); }
|
public boolean splitToplevelSections() { return ((BooleanOption) options[SPLIT_TOPLEVEL_SECTIONS]).getValue(); }
|
||||||
public boolean saveImagesInSubdir() { return ((BooleanOption) options[SAVE_IMAGES_IN_SUBDIR]).getValue(); }
|
public boolean saveImagesInSubdir() { return ((BooleanOption) options[SAVE_IMAGES_IN_SUBDIR]).getValue(); }
|
||||||
|
|
||||||
public Map<String, String> getMathSymbols() {
|
|
||||||
Map<String,String> map = new HashMap<String,String>();
|
|
||||||
for (String sName : mathSymbols.keySet()) {
|
|
||||||
String sLatex = mathSymbols.get(sName).get("latex");
|
|
||||||
map.put(sName, sLatex);
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StyleMap getParStyleMap() { return par; }
|
|
||||||
public StyleMap getParBlockStyleMap() { return parBlock; }
|
|
||||||
public StyleMap getTextStyleMap() { return text; }
|
|
||||||
public StyleMap getListStyleMap() { return list; }
|
|
||||||
public StyleMap getListItemStyleMap() { return listItem; }
|
|
||||||
public StyleMap getTextAttributeStyleMap() { return textAttr; }
|
|
||||||
public HeadingMap getHeadingMap() { return headingMap; }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,11 @@
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
* MA 02111-1307 USA
|
* MA 02111-1307 USA
|
||||||
*
|
*
|
||||||
* Copyright: 2002-2007 by Henrik Just
|
* Copyright: 2002-2009 by Henrik Just
|
||||||
*
|
*
|
||||||
* All Rights Reserved.
|
* All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Version 1.0 (2007-07-30)
|
* Version 1.2 (2009-09-28)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -32,6 +32,16 @@ import java.util.Enumeration;
|
||||||
public class StyleMap {
|
public class StyleMap {
|
||||||
private Hashtable<String, StyleMapItem> items = new Hashtable<String, StyleMapItem>();
|
private Hashtable<String, StyleMapItem> items = new Hashtable<String, StyleMapItem>();
|
||||||
|
|
||||||
|
public void put(String sName, String sBefore, String sAfter, String sNext, boolean bLineBreak, boolean bVerbatim) {
|
||||||
|
StyleMapItem item = new StyleMapItem();
|
||||||
|
item.sBefore = sBefore;
|
||||||
|
item.sAfter = sAfter;
|
||||||
|
item.sNext = ";"+sNext+";";
|
||||||
|
item.bLineBreak = bLineBreak;
|
||||||
|
item.bVerbatim = bVerbatim;
|
||||||
|
items.put(sName,item);
|
||||||
|
}
|
||||||
|
|
||||||
public void put(String sName, String sBefore, String sAfter, boolean bLineBreak, boolean bVerbatim) {
|
public void put(String sName, String sBefore, String sAfter, boolean bLineBreak, boolean bVerbatim) {
|
||||||
StyleMapItem item = new StyleMapItem();
|
StyleMapItem item = new StyleMapItem();
|
||||||
item.sBefore = sBefore;
|
item.sBefore = sBefore;
|
||||||
|
|
|
@ -24,5 +24,20 @@
|
||||||
<dlg:checkbox dlg:id="UseUlem" dlg:tab-index="6" dlg:left="10" dlg:top="78" dlg:width="240" dlg:height="12" dlg:value="Use ulem.sty (underline and strike out text)" dlg:checked="false"/>
|
<dlg:checkbox dlg:id="UseUlem" dlg:tab-index="6" dlg:left="10" dlg:top="78" dlg:width="240" dlg:height="12" dlg:value="Use ulem.sty (underline and strike out text)" dlg:checked="false"/>
|
||||||
<dlg:checkbox dlg:id="UseTitlesec" dlg:tab-index="7" dlg:left="10" dlg:top="92" dlg:width="240" dlg:height="12" dlg:value="Use titlesec.sty to format headings" dlg:checked="false"/>
|
<dlg:checkbox dlg:id="UseTitlesec" dlg:tab-index="7" dlg:left="10" dlg:top="92" dlg:width="240" dlg:height="12" dlg:value="Use titlesec.sty to format headings" dlg:checked="false"/>
|
||||||
<dlg:checkbox dlg:id="UseTitletoc" dlg:tab-index="8" dlg:left="10" dlg:top="106" dlg:width="240" dlg:height="12" dlg:value="Use titletoc.sty to format content tables" dlg:checked="false"/>
|
<dlg:checkbox dlg:id="UseTitletoc" dlg:tab-index="8" dlg:left="10" dlg:top="106" dlg:width="240" dlg:height="12" dlg:value="Use titletoc.sty to format content tables" dlg:checked="false"/>
|
||||||
|
<dlg:text dlg:id="FormattingAttributeLabel" dlg:tab-index="9" dlg:left="10" dlg:top="120" dlg:width="100" dlg:height="12" dlg:value="Character formatting"/>
|
||||||
|
<dlg:menulist dlg:id="FormattingAttribute" dlg:tab-index="10" dlg:left="120" dlg:top="118" dlg:width="130" dlg:height="12" dlg:spin="true">
|
||||||
|
<dlg:menupopup>
|
||||||
|
<dlg:menuitem dlg:value="Bold"/>
|
||||||
|
<dlg:menuitem dlg:value="Italics"/>
|
||||||
|
<dlg:menuitem dlg:value="Small caps"/>
|
||||||
|
<dlg:menuitem dlg:value="Superscript"/>
|
||||||
|
<dlg:menuitem dlg:value="Subscript"/>
|
||||||
|
</dlg:menupopup>
|
||||||
|
</dlg:menulist>
|
||||||
|
<dlg:text dlg:id="BeforeLabel" dlg:tab-index="11" dlg:left="15" dlg:top="148" dlg:width="95" dlg:height="12" dlg:value="LaTeX code before"/>
|
||||||
|
<dlg:textfield dlg:id="Before" dlg:tab-index="12" dlg:left="120" dlg:top="146" dlg:width="130" dlg:height="12"/>
|
||||||
|
<dlg:text dlg:id="AfterLabel" dlg:tab-index="13" dlg:left="15" dlg:top="162" dlg:width="95" dlg:height="12" dlg:value="LaTeX code after"/>
|
||||||
|
<dlg:textfield dlg:id="After" dlg:tab-index="14" dlg:left="120" dlg:top="160" dlg:width="130" dlg:height="12"/>
|
||||||
|
<dlg:checkbox dlg:id="CustomAttribute" dlg:tab-index="15" dlg:left="15" dlg:top="134" dlg:width="235" dlg:height="12" dlg:value="Apply custom LaTeX code" dlg:checked="false"/>
|
||||||
</dlg:bulletinboard>
|
</dlg:bulletinboard>
|
||||||
</dlg:window>
|
</dlg:window>
|
|
@ -3,34 +3,33 @@
|
||||||
<dlg:window xmlns:dlg="http://openoffice.org/2000/dialog" xmlns:script="http://openoffice.org/2000/script" dlg:id="Styles" dlg:left="139" dlg:top="84" dlg:width="260" dlg:height="185" dlg:closeable="true" dlg:moveable="true" dlg:title="Styles" dlg:withtitlebar="false">
|
<dlg:window xmlns:dlg="http://openoffice.org/2000/dialog" xmlns:script="http://openoffice.org/2000/script" dlg:id="Styles" dlg:left="139" dlg:top="84" dlg:width="260" dlg:height="185" dlg:closeable="true" dlg:moveable="true" dlg:title="Styles" dlg:withtitlebar="false">
|
||||||
<dlg:bulletinboard>
|
<dlg:bulletinboard>
|
||||||
<dlg:text dlg:id="StyleFamilyLabel" dlg:tab-index="0" dlg:left="10" dlg:top="8" dlg:width="60" dlg:height="12" dlg:value="Style family"/>
|
<dlg:text dlg:id="StyleFamilyLabel" dlg:tab-index="0" dlg:left="10" dlg:top="8" dlg:width="60" dlg:height="12" dlg:value="Style family"/>
|
||||||
<dlg:menulist dlg:id="StyleFamily" dlg:tab-index="1" dlg:left="80" dlg:top="6" dlg:width="170" dlg:height="12" dlg:spin="true" dlg:linecount="6">
|
<dlg:menulist dlg:id="StyleFamily" dlg:tab-index="1" dlg:left="80" dlg:top="6" dlg:width="170" dlg:height="12" dlg:spin="true">
|
||||||
<dlg:menupopup>
|
<dlg:menupopup>
|
||||||
<dlg:menuitem dlg:value="Character"/>
|
<dlg:menuitem dlg:value="Character"/>
|
||||||
<dlg:menuitem dlg:value="Paragraph"/>
|
<dlg:menuitem dlg:value="Paragraph"/>
|
||||||
<dlg:menuitem dlg:value="Paragraph block"/>
|
<dlg:menuitem dlg:value="Paragraph block"/>
|
||||||
<dlg:menuitem dlg:value="List"/>
|
<dlg:menuitem dlg:value="List"/>
|
||||||
<dlg:menuitem dlg:value="List item"/>
|
<dlg:menuitem dlg:value="List item"/>
|
||||||
<dlg:menuitem dlg:value="Attribute"/>
|
|
||||||
</dlg:menupopup>
|
</dlg:menupopup>
|
||||||
</dlg:menulist>
|
</dlg:menulist>
|
||||||
<dlg:text dlg:id="StyleNameLabel" dlg:tab-index="3" dlg:left="10" dlg:top="22" dlg:width="60" dlg:height="12" dlg:value="Style name"/>
|
<dlg:text dlg:id="StyleNameLabel" dlg:tab-index="3" dlg:left="10" dlg:top="28" dlg:width="60" dlg:height="12" dlg:value="Style name"/>
|
||||||
<dlg:button dlg:id="NewStyleButton" dlg:tab-index="4" dlg:left="165" dlg:top="20" dlg:width="40" dlg:height="12" dlg:value="New..."/>
|
<dlg:button dlg:id="NewStyleButton" dlg:tab-index="4" dlg:left="165" dlg:top="26" dlg:width="40" dlg:height="12" dlg:value="New..."/>
|
||||||
<dlg:button dlg:id="DeleteStyleButton" dlg:tab-index="5" dlg:left="210" dlg:top="20" dlg:width="40" dlg:height="12" dlg:value="Delete..."/>
|
<dlg:button dlg:id="DeleteStyleButton" dlg:tab-index="5" dlg:left="210" dlg:top="26" dlg:width="40" dlg:height="12" dlg:value="Delete..."/>
|
||||||
<dlg:text dlg:id="BeforeLabel" dlg:tab-index="6" dlg:left="10" dlg:top="36" dlg:width="60" dlg:height="12" dlg:value="LaTeX code before"/>
|
<dlg:text dlg:id="BeforeLabel" dlg:tab-index="6" dlg:left="15" dlg:top="42" dlg:width="60" dlg:height="12" dlg:value="LaTeX code before"/>
|
||||||
<dlg:textfield dlg:id="Before" dlg:tab-index="7" dlg:left="80" dlg:top="34" dlg:width="170" dlg:height="12"/>
|
<dlg:textfield dlg:id="Before" dlg:tab-index="7" dlg:left="80" dlg:top="40" dlg:width="170" dlg:height="12"/>
|
||||||
<dlg:text dlg:id="AfterLabel" dlg:tab-index="8" dlg:left="10" dlg:top="50" dlg:width="60" dlg:height="12" dlg:value="LaTeX code after"/>
|
<dlg:text dlg:id="AfterLabel" dlg:tab-index="8" dlg:left="15" dlg:top="56" dlg:width="60" dlg:height="12" dlg:value="LaTeX code after"/>
|
||||||
<dlg:textfield dlg:id="After" dlg:tab-index="9" dlg:left="80" dlg:top="48" dlg:width="170" dlg:height="12"/>
|
<dlg:textfield dlg:id="After" dlg:tab-index="9" dlg:left="80" dlg:top="54" dlg:width="170" dlg:height="12"/>
|
||||||
<dlg:text dlg:id="NextStylesLabel" dlg:tab-index="10" dlg:left="10" dlg:top="64" dlg:width="60" dlg:height="12" dlg:value="Next style(s)"/>
|
<dlg:text dlg:id="NextStylesLabel" dlg:tab-index="10" dlg:left="15" dlg:top="70" dlg:width="60" dlg:height="12" dlg:value="Next style(s)"/>
|
||||||
<dlg:textfield dlg:id="Next" dlg:tab-index="11" dlg:left="80" dlg:top="62" dlg:width="170" dlg:height="12"/>
|
<dlg:textfield dlg:id="Next" dlg:tab-index="11" dlg:left="80" dlg:top="68" dlg:width="170" dlg:height="12"/>
|
||||||
<dlg:checkbox dlg:id="LineBreak" dlg:tab-index="13" dlg:left="10" dlg:top="92" dlg:width="240" dlg:height="12" dlg:value="Line break inside" dlg:checked="false"/>
|
<dlg:checkbox dlg:id="LineBreak" dlg:tab-index="13" dlg:left="15" dlg:top="98" dlg:width="235" dlg:height="12" dlg:value="Line break inside" dlg:checked="false"/>
|
||||||
<dlg:text dlg:id="OtherStylesLabel" dlg:tab-index="14" dlg:left="10" dlg:top="112" dlg:width="60" dlg:height="12" dlg:value="Other styles"/>
|
<dlg:text dlg:id="OtherStylesLabel" dlg:tab-index="14" dlg:left="10" dlg:top="118" dlg:width="60" dlg:height="12" dlg:value="Other styles"/>
|
||||||
<dlg:menulist dlg:id="OtherStyles" dlg:tab-index="15" dlg:left="80" dlg:top="110" dlg:width="170" dlg:height="12" dlg:spin="true">
|
<dlg:menulist dlg:id="OtherStyles" dlg:tab-index="15" dlg:left="80" dlg:top="116" dlg:width="170" dlg:height="12" dlg:spin="true">
|
||||||
<dlg:menupopup>
|
<dlg:menupopup>
|
||||||
<dlg:menuitem dlg:value="Ignore"/>
|
<dlg:menuitem dlg:value="Ignore"/>
|
||||||
<dlg:menuitem dlg:value="Convert"/>
|
<dlg:menuitem dlg:value="Convert"/>
|
||||||
</dlg:menupopup>
|
</dlg:menupopup>
|
||||||
</dlg:menulist>
|
</dlg:menulist>
|
||||||
<dlg:checkbox dlg:id="Verbatim" dlg:tab-index="12" dlg:left="10" dlg:top="78" dlg:width="240" dlg:height="12" dlg:value="Verbatim content" dlg:checked="false"/>
|
<dlg:checkbox dlg:id="Verbatim" dlg:tab-index="12" dlg:left="15" dlg:top="84" dlg:width="235" dlg:height="12" dlg:value="Verbatim content" dlg:checked="false"/>
|
||||||
<dlg:menulist dlg:id="StyleName" dlg:tab-index="2" dlg:left="80" dlg:top="20" dlg:width="80" dlg:height="12" dlg:spin="true"/>
|
<dlg:menulist dlg:id="StyleName" dlg:tab-index="2" dlg:left="80" dlg:top="26" dlg:width="80" dlg:height="12" dlg:spin="true"/>
|
||||||
</dlg:bulletinboard>
|
</dlg:bulletinboard>
|
||||||
</dlg:window>
|
</dlg:window>
|
Loading…
Add table
Reference in a new issue