diff options
Diffstat (limited to 'xmerge/source/minicalc/java/org/openoffice')
9 files changed, 2484 insertions, 0 deletions
diff --git a/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/ConverterCapabilitiesImpl.java b/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/ConverterCapabilitiesImpl.java new file mode 100644 index 000000000000..a1dc67a443e0 --- /dev/null +++ b/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/ConverterCapabilitiesImpl.java @@ -0,0 +1,113 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.minicalc; + +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.OfficeConstants; + + +/** + * <p>MiniCalc implementation of <code>ConverterCapabilities</code> for + * the {@link + * org.openoffice.xmerge.converter.xml.sxc.minicalc.PluginFactoryImpl + * PluginFactoryImpl}.</p> + * + * <p>Used with StarCalc SXC to/from MiniCalc conversions. The + * <code>ConverterCapibilies</code> specify which "Office" + * <code>Document</code> tags and attributes are supported on the + * "Device" <code>Document</code> format.</p> + */ +public final class ConverterCapabilitiesImpl + implements ConverterCapabilities { + + public boolean canConvertTag(String tag) { + + if (OfficeConstants.TAG_OFFICE_BODY.equals(tag)) + return true; + else if (OfficeConstants.TAG_PARAGRAPH.equals(tag)) + return true; + else if (OfficeConstants.TAG_TABLE.equals(tag)) + return true; + else if (OfficeConstants.TAG_TABLE_ROW.equals(tag)) + return true; + else if (OfficeConstants.TAG_TABLE_COLUMN.equals(tag)) + return false; + // TODO - we currently do not handle the table column tag + else if (OfficeConstants.TAG_TABLE_SCENARIO.equals(tag)) + return false; + // TODO - we currently do not handle the table scenario tag + else if (OfficeConstants.TAG_TABLE_CELL.equals(tag)) + return true; + + return false; + } + + public boolean canConvertAttribute(String tag, + String attribute) { + + if (OfficeConstants.TAG_TABLE.equals(tag)) { + + if (OfficeConstants.ATTRIBUTE_TABLE_NAME.equals(attribute)) + return true; + + } else if (OfficeConstants.TAG_TABLE_CELL.equals(tag)) { + + if (OfficeConstants.ATTRIBUTE_TABLE_VALUE_TYPE.equals(attribute)) + return true; + else if (OfficeConstants.ATTRIBUTE_TABLE_FORMULA. + equals(attribute)) + return true; + else if (OfficeConstants.ATTRIBUTE_TABLE_VALUE.equals(attribute)) + return true; + else if (OfficeConstants.ATTRIBUTE_TABLE_BOOLEAN_VALUE. + equals(attribute)) + return true; + else if (OfficeConstants.ATTRIBUTE_TABLE_CURRENCY. + equals(attribute)) + return true; + else if (OfficeConstants.ATTRIBUTE_TABLE_TIME_VALUE. + equals(attribute)) + return true; + else if (OfficeConstants.ATTRIBUTE_TABLE_DATE_VALUE. + equals(attribute)) + return true; + else if (OfficeConstants.ATTRIBUTE_TABLE_NUM_COLUMNS_REPEATED. + equals(attribute)) + return true; + + } else if (OfficeConstants.TAG_TABLE_ROW.equals(tag)) { + + if (OfficeConstants.ATTRIBUTE_TABLE_NUM_ROWS_REPEATED. + equals(attribute)) + return true; + } + + return false; + } +} + diff --git a/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcConstants.java b/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcConstants.java new file mode 100644 index 000000000000..78d48a5e4ee9 --- /dev/null +++ b/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcConstants.java @@ -0,0 +1,45 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.minicalc; + +import org.openoffice.xmerge.converter.palm.PdbUtil; + +/** + * Constants used for encoding and decoding the MiniCalc format. + * + * @author Herbie Ong + */ +interface MinicalcConstants { + + /** Creator ID. */ + public static final int CREATOR_ID = PdbUtil.intID("PiMC"); + + /** Type ID. */ + public static final int TYPE_ID = PdbUtil.intID("Data"); +} + diff --git a/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcDataString.java b/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcDataString.java new file mode 100644 index 000000000000..974e9d1b3079 --- /dev/null +++ b/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcDataString.java @@ -0,0 +1,545 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.minicalc; + +/** + * This class is used by <code>MinicalcDecoder</code> to manipulate a + * <code>String</code> containing MiniCalc cell data. + * + * @author Paul Rank + */ +public class MinicalcDataString { + + /** The String representation of the MiniCalc data. */ + private String data = null; + + + /** + * Constructor stores the MiniCalc data <code>String</code>. + * + * @param data A <code>String</code> containing MiniCalc + * cell data. + */ + public MinicalcDataString(String data) { + this.data = data; + } + + + /** + * Checks if the MiniCalc data <code>String</code> is a <i>formula</i>. + * + * @return true if the MiniCalc data <code>String</code> is a + * <i>formula</i>, false if the MiniCalc data <code>String</code> + * is not a <i>formula</i>. + */ + public boolean isFormula() { + + if (data.startsWith("=")) { + return true; + } + + return false; + } + + + /** + * Checks if the MiniCalc data <code>String</code> is a <i>percentage</i>. + * + * @return true if the MiniCalc data <code>String</code> is a + * <i>percentage</i>, false if the MiniCalc data + * <code>String</code> is not a <i>percentage</i>. + */ + public boolean isPercent() { + + if (data.endsWith("%")) { + return true; + } + + return false; + } + + + /** + * Checks if the MiniCalc data <code>String</code> is a + * <i>boolean</i> value. + * + * @return true if the MiniCalc data <code>String</code> is + * a <i>boolean</i>, false if the MiniCalc data + * <code>String</code> is not a <i>boolean</i>. + */ + public boolean isBoolean() { + + if (data.equalsIgnoreCase("false") || + data.equalsIgnoreCase("true")) { + return true; + } + + return false; + } + + + /** + * Checks if the MiniCalc data <code>String</code> is a <i>date</i>. + * + * @return true if the MiniCalc data <code>String</code> is + * a <i>date</i>, false if the MiniCalc data <code>String</code> + * is not a <i>date</i>. + */ + public boolean isDate() { + + // Starting index into the date string - month + int start = 0; + + // Search for "/", which separates month from day + int end = data.indexOf("/"); + + // Separator was found + if (end > 0) { + + String monthString = data.substring(start, end); + + try { + Float f = Float.valueOf(monthString); + if ((f.intValue() < 0) || (f.intValue() > 12)) { + return false; + } + } + catch (NumberFormatException e) { + + // no, it is not a currency type + return false; + } + + // start is now the starting index of day + start = end+1; + + // Search for "/", which separates day from year + end = data.indexOf("/", start); + + // Separator was found + if (end > 0) { + + String dayString = data.substring(start, end); + + try { + Float f = Float.valueOf(dayString); + if ((f.intValue() < 0) || (f.intValue() > 31)) + return false; + } + catch (NumberFormatException e) { + // no, it is not a currency type + return false; + } + } else { + return false; + } + + // start is now at the starting index of the year + start = end + 1; + + String yearString = data.substring(start); + try { + Float f = Float.valueOf(yearString); + if (f.intValue() < 0) { + return false; + } + } + catch (NumberFormatException e) { + // no, it is not a currency type + return false; + } + + } else { + return false; + } + + return true; + } + + + /** + * Checks if the MiniCalc data <code>String</code> is a <i>time</i>. + * + * @return true if the MiniCalc data <code>String</code> + * is a <i>time</i>, false if the MiniCalc data + * <code>String</code> is not a <i>time</i>. + */ + public boolean isTime() { + + // Starting index into the time string - hour + int start = 0; + + // Search for ":", which separates hour from minute + int end = data.indexOf(":"); + + + // Separator was found + if (end > 0) { + + String hourString = data.substring(start, end); + try { + Float f = Float.valueOf(hourString); + if ((f.intValue() < 0) || (f.intValue() > 24)) + return false; + } + catch (NumberFormatException e) { + // no, it is not a time type + return false; + } + + // start is now the starting index of minute + start = end+1; + + // Search for ":", which separates minute from second + end = data.indexOf(":", start); + + // Separator was found + if (end > 0) { + + String minuteString = data.substring(start, end); + + try { + Float f = Float.valueOf(minuteString); + if ((f.intValue() < 0) || (f.intValue() > 60)) + return false; + } + catch (NumberFormatException e) { + // no, it is not a time type + return false; + } + + // start is now at the starting index of the seconds + start = end+1; + + // The seconds are in the string + if (data.length() > start) { + + String secondString = data.substring(start); + + + try { + Float f = Float.valueOf(secondString); + if ((f.intValue() < 0) || (f.intValue() > 60)) + return false; + } + catch (NumberFormatException e) { + // no, it is not a time type + return false; + } + } + + } + + return true; + + } + + return false; + } + + + /** + * Checks if the MiniCalc data <code>String</code> is a <i>currency</i> + * value. + * + * @return true if the MiniCalc data <code>String</code> is + * a <i>currency</i>, false if the MiniCalc data + * <code>String</code> is not a <i>currency</i>. + */ + public boolean isCurrency() { + + boolean result = false; + + // TODO - we currently only check for US currencies + + if (data.endsWith("$")) { + String number = data.substring(0, data.length()-1); + try { + Float f = Float.valueOf(number); + result = true; + } + catch (NumberFormatException e) { + // no, it is not a currency type + result = false; + } + } + + else if (data.startsWith("$")) { + String number = data.substring(1, data.length()); + try { + Float f = Float.valueOf(number); + result = true; + } + catch (NumberFormatException e) { + // no, it is not a currency type + result = false; + } + } + + return result; + + } + + + /** + * This method removes the percent sign from the MiniCalc data + * <code>String</code>. If the percent sign is not the last + * character of the MiniCalc data <code>String</code>, the + * MiniCalc data <code>String</code> is returned. + * + * @return The MiniCalc data <code>String</code> minus the + * percent sign. If the MiniCalc data <code>String</code> + * does not begin with a percent sign, the MiniCalc data + * <code>String</code> is returned. + */ + public String percentRemoveSign() { + + String number = data; + + if (data.endsWith("%")) { + // "%" is the last character, so remove + number = data.substring(0, data.length()-1); + + try { + Float f = Float.valueOf(number); + float f1 = f.floatValue()/100f; + Float f2 = new Float(f1); + number = f2.toString(); + } + catch (NumberFormatException e) { + // no, it is not a float type + } + } + + return number; + } + + + /** + * This method removes the currency sign from the MiniCalc data + * <code>String</code>. If the currency sign is not the first or + * last character of the MiniCalc data <code>String</code>, the + * MiniCalc data <code>String</code> is returned. + * + * @return The MiniCalc data <code>String</code> minus the currency + * sign. If the MiniCalc data <code>String</code> does not + * begin or end with a currency sign, the MiniCalc + * data <code>String</code> is returned. + */ + public String currencyRemoveSign() { + + String number = data; + + // TODO - only works with US currencies + + if (data.endsWith("$")) { + + number = data.substring(0, data.length()-1); + + } else if (data.startsWith("$")) { + + number = data.substring(1, data.length()); + } + + return number; + + } + + + /** + * <p>This method converts a MiniCalc date from MiniCalc + * format to StarOffice XML format.</p> + * + * <p>MiniCalc format:</p> + * + * <p><blockquote> + * MM/DD/YY or MM/DD/YYYY + * </blockquote></p> + * + * <p>StarOffice XML format:</p> + * + * <p><blockquote> + * YYYY-MM-DD + * </blockquote></p> + * + * @return The MiniCalc date converted to StarOffice XML + * format. + */ + public String convertToStarDate() { + + // The output date string + String out; + + String monthString = "01"; + String dayString = "01"; + String yearString = "1900"; + + // Starting index into the date string - month + int start = 0; + + // Search for "/", which separates month from day + int end = data.indexOf("/"); + + // Separator was found + if (end > 0) { + + monthString = data.substring(start, end); + + Integer monthInt = new Integer(monthString); + + // Make sure month is 2 digits + if (monthInt.intValue() < 10) { + monthString = "0" + monthString; + } + + // start is now the starting index of day + start = end+1; + + // Search for "/", which separates day from year + end = data.indexOf("/", start); + + // Separator was found + if (end > 0) { + + dayString = data.substring(start, end); + + Integer dayInt = new Integer(dayString); + + // Make sure day is 2 digits + if (dayInt.intValue() < 10) { + dayString = "0" + dayString; + } + + // start is now at the starting index of the year + start = end + 1; + + // The year is in the string + if (data.length() > start) { + + yearString = data.substring(start); + + Integer yearInt = new Integer(yearString); + int year = yearInt.intValue(); + + if (year < 31) { + + // MiniCalc years between 0 and 30 correspond to + // 2000 - 2030 + year += 2000; + + } else if (year < 100) { + + // MiniCalc years between 31 and 99 correspond + // to 1931 - 1999 + year += 1900; + } + + yearString = Integer.toString(year); + } + } + } + + // Set out to StarOffice XML date format + out = yearString + "-" + monthString + "-" + dayString; + + return out; + } + + + /** + * This method converts the MiniCalc time from MiniCalc + * format to StarOffice XML format. + * + * <p>MiniCalc format:</p> + * + * <p><blockquote> + * hh:mm:ss + * </blockquote></p> + * + * <p>StarOffice XML format:</p> + * + * <p><blockquote> + * PThhHmmMssS + * </blockquote></p> + * + * @return The MiniCalc time converted to StarOffice XML + * format. + */ + public String convertToStarTime() { + + // The output time string + String out; + + String hourString = "00"; + String minuteString = "00"; + String secondString = "00"; + + // Starting index into the time string - hour + int start = 0; + + // Search for ":", which separates hour from minute + int end = data.indexOf(":"); + + // Separator was found + if (end > 0) { + + hourString = data.substring(start, end); + + // start is now the starting index of minute + start = end+1; + + // Search for ":", which separates minute from second + end = data.indexOf(":", start); + + // Separator was found + if (end > 0) { + + minuteString = data.substring(start, end); + + // start is now at the starting index of the seconds + start = end+1; + + // The seconds are in the string + if (data.length() > start) { + + secondString = data.substring(start); + } + + } + } + + // TODO - PT is for pacific time, where can we get the + // localized value from? + + // Set to StarOffice XML time format + out = "PT"+hourString+"H"+minuteString+"M"+secondString+"S"; + + return out; + } +} + diff --git a/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcDecoder.java b/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcDecoder.java new file mode 100644 index 000000000000..cd872329b596 --- /dev/null +++ b/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcDecoder.java @@ -0,0 +1,738 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.minicalc; + +import jmc.Workbook; +import jmc.Worksheet; +import jmc.CellAttributes; +import jmc.CellDescriptor; +import jmc.JMCconstants; +import jmc.JMCException; + +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Enumeration; + +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.converter.xml.OfficeConstants; +import org.openoffice.xmerge.converter.palm.PalmDB; +import org.openoffice.xmerge.converter.palm.Record; +import org.openoffice.xmerge.converter.palm.PalmDocument; +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.converter.xml.sxc.SxcDocumentDeserializer; +import org.openoffice.xmerge.converter.xml.sxc.SpreadsheetDecoder; +import org.openoffice.xmerge.converter.xml.sxc.Format; + +/** + * This class is used by {@link + * org.openoffice.xmerge.converter.xml.sxc.SxcDocumentDeserializerImpl} + * SxcDocumentDeserializerImpl} to decode the MiniCalc format. + * + * @author Paul Rank + */ +final class MinicalcDecoder extends SpreadsheetDecoder { + + /** MiniCalc WorkBook to store sheets. */ + private Workbook wb; + + /** MiniCalc sheet - only one sheet can be open at a time. */ + private Worksheet ws; + + /** The current cell - only one cell can be active at a time. */ + private CellDescriptor cell = null; + + /** Format object describing the current cell. */ + private Format fmt = null; + + /** The password for the WorkBook. */ + private String password = null; + + /** The number of rows in the current WorkSheet. */ + private int maxRows = 0; + + /** The number of columns in the current WorkSheet. */ + private int maxCols = 0; + + /** The names of the worksheets. */ + private String[] worksheetNames = null; + + /** + * Constructor creates a MiniCalc WorkBook. + * + * @param name The name of the WorkBook. + * @param password The password for the workBook. + * + * @throws IOException If any I/O error occurs. + */ + MinicalcDecoder(String name, String[] worksheetNames, String password) throws IOException { + + super(name, password); + + fmt = new Format(); + + this.password = password; + this.worksheetNames = worksheetNames; + + try { + + wb = new Workbook(name, password); + + } + catch (JMCException e) { + + Debug.log(Debug.ERROR, "MinicalcDecoder.constructor:" + e.getMessage()); + + throw new IOException(e.getMessage()); + } + } + + + /** + * This method takes a <code>ConvertData</code> as input and + * converts it into a MiniCalc WorkSheet. The WorkSheet is then + * added to the WorkBook. + * + * @param InputStream An <code>ConvertData</code> containing a + * MiniCalc WorkSheet. + * + * @throws IOException If any I/O error occurs. + */ + public void addDeviceContent(ConvertData cd) throws IOException { + + try { + PalmDocument palmDoc; + int j = 0; + + Enumeration e = cd.getDocumentEnumeration(); + while(e.hasMoreElements()) { + + palmDoc = (PalmDocument) e.nextElement(); + // Convert PDB to WorkBook/WorkSheet format + PalmDB pdb = palmDoc.getPdb(); + + // This will be done at least once + String sheetName = worksheetNames[j]; + + // Get number of records in the pdb + int numRecords = pdb.getRecordCount(); + + // sheetName does not contain the WorkBook name, but we need the + // full name. + String fullSheetName = new String(wb.getWorkbookName() + "-" + sheetName); + + // Create a new (empty) WorkSheet + ws = new Worksheet(); + + // Initialize the WorkSheet + ws.initWorksheet(fullSheetName, numRecords); + + // Loop over the number of records in the PDB + for (int i = 0; i < numRecords; i++) { + + // Read record i from the PDB + Record rec = pdb.getRecord(i); + + byte cBytes[] = rec.getBytes(); + + // Create an InputStream + ByteArrayInputStream bis = new ByteArrayInputStream(cBytes); + + // Get the size of the stream + int bisSize = cBytes.length; + + // Add each record to the WorkSheet + ws.readNextRecord(bis, bisSize); + } + + + // Add the WorkSheet to the WorkBook + wb.addWorksheet(ws); + j++; + } + } + catch (JMCException e) { + + Debug.log(Debug.ERROR, "MinicalcDecoder.addPDB:" + e.getMessage()); + + throw new IOException(e.getMessage()); + } + } + + + /** + * This method returns the number of spreadsheets + * stored in the WorkBook. + * + * @return The number of sheets in the WorkBook. + */ + public int getNumberOfSheets() { + + return wb.getNumberOfSheets(); + } + + + /** + * This method gets the requested WorkSheet from the + * WorkBook and sets it as the selected WorkSheet. All + * other "get" methods will now get data from this WorkSheet. + * + * @param sheetIndex The index number of the sheet to open. + * + * @throws IOException If any I/O error occurs. + */ + public void setWorksheet(int sheetIndex) throws IOException { + + try { + + ws = wb.getWorksheet(sheetIndex); + + // Initialize access to the WorkSheet so that we can calculate + // the number of rows and columns + ws.initAccess(password); + + maxRows = 0; + maxCols = 0; + + while (goToNextCell()) { + maxRows = Math.max(maxRows, cell.getRowNumber()); + maxCols = Math.max(maxCols, cell.getColNumber()); + } + + // Re-initialize access to the WorkSheet + ws.initAccess(password); + + } + catch (JMCException e) { + + Debug.log(Debug.ERROR, "MinicalcDecoder.setWorksheet:" + e.getMessage()); + + throw new IOException(e.getMessage()); + } + } + + + /** + * This method returns the name of the current spreadsheet. + * + * @return The name of the current WorkSheet. + */ + public String getSheetName() { + + String sheetName = ws.getName(); + + return sheetName; + } + + + /** + * This method gets the next cell from the WorkSheet + * and sets it as the selected cell. All other "get" + * methods will now get data from this cell. + * + * @return True if we were able to go to another cell + * in the sheet, false if there were no cells + * left. + * + * @throws IOException If any I/O error occurs. + */ + public boolean goToNextCell() throws IOException { + + boolean gotCell = false; + + try { + cell = ws.getNextCell(); + + if (cell != null) { + gotCell = true; + } + + // As we read each cell, get its formatting info + readCellFormat(); + } + catch (JMCException e) { + + Debug.log(Debug.ERROR, "MinicalcDecoder.goToNextCell:" + e.getMessage()); + + throw new IOException(e.getMessage()); + } + + return gotCell; + } + + + /** + * This method returns the row number of the current cell. + * + * @return The row number of the current cell. Returns + * -1 if no cell is currently selected. + */ + public int getRowNumber() { + + int row = -1; + + if (cell != null) { + + row = cell.getRowNumber(); + } + + return row; + } + + /** + * This method returns the number of rows in the current sheet. + * + * @return The number of rows in the current sheet. + */ + public int getNumberOfRows() { + + return maxRows; + } + + /** + * This method returns the number of columns in the current sheet. + * + * @return The number of columns in the current sheet. + */ + public int getNumberOfColumns() { + return maxCols; + } + + + /** + * This method returns the col number of the current cell. + * + * @return The col number of the current cell. Returns + * -1 if no cell is currently selected. + */ + public int getColNumber() { + + int col = -1; + + if (cell != null) { + + col = cell.getColNumber(); + } + + return col; + } + + + /** + * This method returns the contents of the current cell. + * + * @return The contents of the current cell. Returns + * null if no cell is currently selected. + */ + public String getCellContents() { + + String contents = null; + + if (cell != null) { + contents = cell.getCellContents(); + + // Active cell, but no content + if (contents == null) + return new String(""); + + // Does the cell contain a formula? + if (contents.startsWith("=")) { + contents = parseFormula(contents); + } + // Make sure that any MiniCalc peculiarities are stripped off + if (fmt.getCategory().equalsIgnoreCase(OfficeConstants.CELLTYPE_CURRENCY)) { + contents = currencyRemoveSign(contents); + } + else if (fmt.getCategory().equalsIgnoreCase(OfficeConstants.CELLTYPE_PERCENT)) { + contents = percentRemoveSign(contents); + } + else if (fmt.getCategory().equalsIgnoreCase(OfficeConstants.CELLTYPE_DATE)) { + contents = convertToStarDate(contents); + } + else if (fmt.getCategory().equalsIgnoreCase(OfficeConstants.CELLTYPE_TIME)) { + contents = convertToStarTime(contents); + } + } + + return contents; + } + + /** + * This method is meant to return the value of the formula cell. However + * in minicalc this value is not used so hence the stubbed function + * + * @return the value fo the formula cell + */ + public String getCellValue() { + return null; + } + + /** + * <p>This method takes a formula and parses it into + * StarOffice XML formula format.</p> + * + * <p>Many spreadsheets use ',' as a separator. + * StarOffice XML format uses ';' as a separator instead.</p> + * + * <p>Many spreadsheets use '!' as a separator when refencing + * a cell in a different sheet.</p> + * + * <blockquote> + * Example: =sheet1!A1 + * </blockquote> + * + * <p>StarOffice XML format uses '.' as a separator instead.</p> + * + * <blockquote> + * Example: =sheet1.A1 + * </blockquote> + * + * @param formula A formula string. + * + * @return A StarOffice XML format formula string. + */ + protected String parseFormula(String formula) { + + formula = formula.replace(',', ';'); + formula = formula.replace('!', '.'); + + return formula; + } + + /** + * <p>This method returns the type of the data in the current cell.</p> + * + * <p>Possible Data Types:</p> + * + * <ul><li> + * Percent - MiniCalc can store as a number or as a string. + * + * When stored as a string, the % sign is stored in the + * string . The MiniCalc format is "string". + * Example 10.1% is stored as the string "10.1%" + * + * When stored as a number, the decimal representation + * is stored. The MiniCalc format is "percentage". + * Example: 10.1% is stored as "0.101" + * </li><li> + * Currency - MiniCalc stores currency as a number with the format + * set to "currency". + * A user can also enter a value with a dollar sign + * (example $18.56) into MiniCalc and not set the format + * as currency. We treat this type of data as a + * currency data type. + * </li><li> + * Boolean - MiniCalc stores in a string as "true" or "false" + * </li><li> + * + * Date - MiniCalc stores a date in a string as either + * MM/DD/YY or MM/DD/YYYY. Any variation from the above + * format will not be considered a date. + * </li><li> + * Time - MiniCalc stores a time in a string as hh:mm:ss. Any + * variation from this format will not be considered a time. + * </li><li> + * Float - MiniCalc stores as a number and it is not percent + * or currency. + * </li><li> + * String - MiniCalc stores as a string (surprise). Doesn't parse + * to any of the other data types. + * </li><li> + * @return The type of the data in the current cell. + * </li></ul> + */ + public String getCellDataType() { + + boolean isNumber = false; + + // Get format value set on the cell in MiniCalc + String format = getCellFormatType(); + + // Initialize the data type to the format + String type = format; + + String contents = getCellContents(); + + if (contents != null) { + + MinicalcDataString data = new MinicalcDataString(contents); + + // Check if it is a formula + if (data.isFormula()) { + Debug.log(Debug.INFO, " " + contents + " Is a Function Format = " + + format + "\n"); + return type; + } + + try { + // Check to see if it is a number + Double d = Double.valueOf(contents); + isNumber = true; + Debug.log(Debug.INFO, " " + contents + " Is a Number Format = " + format); + + } catch (NumberFormatException e) { + Debug.log(Debug.INFO, " " + contents + " Not a Number Format= " + format); + // no, it is not a number + isNumber = false; + } + + + if (isNumber) { + + // Numbers are Float, Currency, and Percent + if (format.equals(OfficeConstants.CELLTYPE_CURRENCY)) { + + type = OfficeConstants.CELLTYPE_CURRENCY; + + } else if (format.equals(OfficeConstants.CELLTYPE_PERCENT)) { + + type = OfficeConstants.CELLTYPE_PERCENT; + + } else { + + type = OfficeConstants.CELLTYPE_FLOAT; + } + + } else if (data.isBoolean()) { + + // Data is a Boolean type + type = OfficeConstants.CELLTYPE_BOOLEAN; + + } else if (data.isDate()) { + + // Data is a Date type + type = OfficeConstants.CELLTYPE_DATE; + + } else if (data.isTime()) { + + // Data is a Time type + type = OfficeConstants.CELLTYPE_TIME; + + } else if (data.isPercent()) { + + // Data is percent + type = OfficeConstants.CELLTYPE_PERCENT; + + } else if (data.isCurrency()) { + + // Data is a Currency type + type = OfficeConstants.CELLTYPE_CURRENCY; + + } else { + + // Data can't be float, since it isn't a number + + // We've already tried parsing it as all other data + // types, the only remaining option is a string + type = OfficeConstants.CELLTYPE_STRING; + } + } + + Debug.log(Debug.INFO, " TYPE = " + type + "\n"); + + return type; + } + + + /** + * This method returns the format of the data in the current cell. + * + * @return The format of the data in the current cell. + */ + String getCellFormatType() { + + // Set type to default data type + String type = OfficeConstants.CELLTYPE_FLOAT; + + if (cell != null) { + + // Get the attributes for the current cell + CellAttributes att = cell.getCellAttributes(); + + if (att != null) { + + // Extract the format info from the attributes + long format = att.getFormat(); + + // The cell type is stored in bits 5-8 + long cellType = format & 0x000000F0L; + + // The number of decimal places is stored in bits 1-4 + long decimals = format & 0x0000000FL; + + if (cellType == JMCconstants.FF_FORMAT_GENERIC) { + + // MiniCalc stores both Strings and Booleans + // in the generic type. We must check the contents + // to differentiate between the two. + + // Get cell's contents + String contents = getCellContents(); + + if (contents.equalsIgnoreCase("false") || + contents.equalsIgnoreCase("true")) { + + type = OfficeConstants.CELLTYPE_BOOLEAN; + + + } else { + + type = OfficeConstants.CELLTYPE_STRING; + + } + + } else if (cellType == JMCconstants.FF_FORMAT_DECIMAL) { + + type = OfficeConstants.CELLTYPE_FLOAT; + + } else if (cellType == JMCconstants.FF_FORMAT_TIME) { + + type = OfficeConstants.CELLTYPE_TIME; + + } else if (cellType == JMCconstants.FF_FORMAT_DATE) { + + type = OfficeConstants.CELLTYPE_DATE; + + } else if (cellType == JMCconstants.FF_FORMAT_CURRENCY) { + + type = OfficeConstants.CELLTYPE_CURRENCY; + + } else if (cellType == JMCconstants.FF_FORMAT_PERCENT) { + + type = OfficeConstants.CELLTYPE_PERCENT; + } + + } + } + + return type; + } + + + /** + * This method takes a <code>String</code> that contains a + * currency value and removes the $ from the <code>String</code>. + * If the dollar sign is not the first or last character of the + * input <code>String</code>, the input <code>String</code> is + * simply returned. + * + * @param contents The input <code>String</code> from which to + * remove the dollar sign. + * + * @return The input <code>String</code> minus the dollar sign. + * If the input <code>String</code> did not begin or end + * with a dollar sign, contents is returned. + */ + private String currencyRemoveSign(String contents) { + MinicalcDataString mcString = new MinicalcDataString(contents); + String currencyString = mcString.currencyRemoveSign(); + return currencyString; + } + + + /** + * This method takes a <code>String</code> that contains a percent + * value and removes the % from the <code>String</code>. If the + * percent sign is not the last character of the input + * <code>String</code>, the input <code>String</code> is simply + * returned. + * + * @param contents The input String from which to remove the + * percent sign. + * + * @return The input <code>String</code> minus the percent sign. + * If the input <code>String</code> did not begin with + * a percent sign, contents is returned. + */ + private String percentRemoveSign(String contents) { + MinicalcDataString mcString = new MinicalcDataString(contents); + String percentString = mcString.percentRemoveSign(); + return percentString; + } + + + /** + * This method returns takes a <code>String</code> that contains + * a time value and converts it from MiniCalc format to StarOffice + * XML time format. + * + * @param contents The input <code>String</code> containing a + * MiniCalc time. + * + * @return The input <code>String</code> converted to StarOffice + * XML time format. + */ + private String convertToStarTime(String contents) { + MinicalcDataString mcString = new MinicalcDataString(contents); + String timeString = mcString.convertToStarTime(); + return timeString; + } + + /** + * This method returns takes a <code>String</code> that contains + * a date value and converts it from MiniCalc format to StarOffice + * XML date format. + * + * @param contents The input <code>String</code> containing a + * MiniCalc date. + * + * @return The input <code>String</code> converted to StarOffice + * XML date format. + */ + private String convertToStarDate(String contents) { + MinicalcDataString mcString = new MinicalcDataString(contents); + String dateString = mcString.convertToStarDate(); + return dateString; + } + + + /** + * Return the Format object describing the active cell formatting. + * + * @return The Format object describing the active cell formatting. + */ + public Format getCellFormat() { + return new Format(fmt); + } + + + /** + * Create the format data for the new cell. + */ + private void readCellFormat() { + // Make sure there are no remnants from the last time + fmt.clearFormatting(); + + fmt.setCategory(getCellFormatType()); + + // TODO - Get any more formatting data here + } +} + diff --git a/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcEncoder.java b/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcEncoder.java new file mode 100644 index 000000000000..14e256918886 --- /dev/null +++ b/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcEncoder.java @@ -0,0 +1,582 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.minicalc; + +import jmc.Workbook; +import jmc.Worksheet; +import jmc.CellAttributes; +import jmc.CellDescriptor; +import jmc.JMCconstants; +import jmc.JMCException; + +import java.awt.Color; + +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; +import java.io.DataOutputStream; +import java.io.IOException; + +import org.openoffice.xmerge.converter.palm.Record; +import org.openoffice.xmerge.util.Debug; +import org.openoffice.xmerge.util.IntArrayList; + +import org.openoffice.xmerge.converter.xml.sxc.SpreadsheetEncoder; +import org.openoffice.xmerge.converter.xml.sxc.Format; +import org.openoffice.xmerge.converter.xml.OfficeConstants; + +/** + * This class is used by {@link + * org.openoffice.xmerge.converter.xml.sxc.SxcDocumentSerializerImpl + * SxcDocumentSerializerImpl} to encode the MiniCalc format. + * + * @author Paul Rank + */ +final class MinicalcEncoder extends SpreadsheetEncoder { + + /** MiniCalc WorkBook to store sheets. */ + private Workbook wb; + + /** MiniCalc sheet - only one sheet can be open at a time. */ + private Worksheet ws; + + /** + * Estimate of the number of Palm pixels per character. Used for + * estimating the width of a cell on a Palm device. + */ + private final static int pixelsPerChar = 6; + + /** + * The minimum width (in pixels) that we allow a column to be set to + * on a Palm device. + */ + private final static int minWidth = 10; + + /** + * The maximum width (in pixels) that we allow a column to be set to + * on a Palm device. + */ + private final static int maxWidth = 80; + + + /** + * Constructor creates a MiniCalc WorkBook. + * + * @param log Log object for logging. + * @param name The name of the WorkBook. + * @param password The password for the WorkBook. + * + * @throws IOException If any I/O error occurs. + */ + MinicalcEncoder(String name, String password) throws IOException { + + super(name, password); + + try { + wb = new Workbook(name, password); + } + catch (JMCException e) { + Debug.log(Debug.ERROR, "new Workbook threw exception:" + e.getMessage()); + throw new IOException(e.getMessage()); + } + } + + + /** + * This method creates a WorkSheet belonging to the + * WorkBook. + * + * @param sheetName The name of the WorkSheet. + * + * @throws IOException If any I/O error occurs. + */ + public void createWorksheet(String sheetName) throws IOException { + + try { + ws = wb.createWorksheet(sheetName); + } + catch (JMCException e) { + Debug.log(Debug.ERROR, "wb.createWorksheet threw exception:" + e.getMessage()); + throw new IOException(e.getMessage()); + } + } + + + /** + * This method gets the number of sheets in the WorkBook. + * + * @return The number of sheets in the WorkBook. + */ + public int getNumberOfSheets() { + + int numSheets = wb.getNumberOfSheets(); + return numSheets; + } + + + /** + * This method encodes the MiniCalc WorkBook information + * into an palm <code>Record</code> array in MiniCalc + * database format. + * + * @return Array of <code>Record</code> holding MiniCalc + * contents. + * + * @throws IOException If any I/O error occurs. + */ + public Record[] getRecords(int sheetID) throws IOException { + + // Get the WorkSheet for the input sheetID + ws = wb.getWorksheet(sheetID); + + // Need to call ws.initWrite() before we start querying the WorkSheet + try { + ws.initWrite(); + } + catch (JMCException e) { + Debug.log(Debug.ERROR, "ws.initWrite in getRecords:" + e.getMessage()); + throw new IOException(e.getMessage()); + } + + // Get the number of records in the WorkSheet + int numRecords = ws.getNumberOfRecords(); + + // Create the Record array + Record[] allRecords = new Record[numRecords]; + + + // Get each record from the WorkSheet and store in allRecords[] + try { + for (int i = 0; i < allRecords.length; i++) { + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + + int length = ws.writeNextRecord(bos); + + byte cBytes[] = bos.toByteArray(); + + allRecords[i] = new Record(cBytes); + } + } + catch (Exception e) { + Debug.log(Debug.ERROR, "ws.writeNextRecord in getRecords:" + e.getMessage()); + throw new IOException(e.getMessage()); + } + + return allRecords; + } + + + /** + * A cell reference in a StarOffice formula looks like + * [.C2] (for cell C2). MiniCalc is expecting cell references + * to look like C2. This method strips out the braces and + * the period. + * + * @param formula A StarOffice formula <code>String</code>. + * + * @return A MiniCalc formula <code>String</code>. + */ + protected String parseFormula(String formula) { + + StringBuffer inFormula = new StringBuffer(formula); + StringBuffer outFormula = new StringBuffer(); + + boolean inBrace = false; + boolean firstCharAfterBrace = false; + boolean firstCharAfterColon = false; + + int len = inFormula.length(); + + for (int in = 0; in < len; in++) { + switch (inFormula.charAt(in)) { + case '[': + // We are now inside a StarOffice cell reference. + // We also need to strip out the '[' + inBrace = true; + + // If the next character is a '.', we want to strip it out + firstCharAfterBrace = true; + break; + + case ']': + // We are exiting a StarOffice cell reference + // We are stripping out the ']' + inBrace = false; + break; + + case ':': + // We have a cell range reference. + // May need to strip out the leading '.' + if (inBrace) + firstCharAfterColon = true; + outFormula.append(inFormula.charAt(in)); + break; + + case '.': + if (inBrace == true) { + if (firstCharAfterBrace == false && + firstCharAfterColon == false) { + // Not the first character after the open brace. + // We have hit a separator between a sheet reference + // and a cell reference. MiniCalc uses a ! as + // this type of separator. + outFormula.append('!'); + } + else { + firstCharAfterBrace = false; + firstCharAfterColon = false; + // Since we are in a StarOffice cell reference, + // and we are the first character, we need to + // strip out the '.' + } + break; + } else { + // We hit valid data, lets add it to the formula string + outFormula.append(inFormula.charAt(in)); + break; + } + + case ';': + // StarOffice XML format uses ';' as a separator. MiniCalc (and + // many spreadsheets) use ',' as a separator instead. + outFormula.append(','); + break; + + default: + // We hit valid data, lets add it to the formula string + outFormula.append(inFormula.charAt(in)); + + // Need to make sure that firstCharAfterBrace is not true. + firstCharAfterBrace = false; + break; + } + } + + return outFormula.toString(); + } + + /** + * Add a cell to the current WorkSheet. + * + * @param row The row number of the cell. + * @param column The column number of the cell. + * @param fmt The <code>Format</code> object describing + * the appearance of this cell. + * @param cellContents The text or formula of the cell's contents. + * + * @throws IOException If any I/O error occurs. + */ + public void addCell(int row, int column, Format fmt, String cellContents) throws IOException { + + CellAttributes ca = new CellAttributes(getFormat(fmt), + fmt.getForeground(), + fmt.getBackground()); + if (cellContents.startsWith("=")) { + cellContents = parseFormula(cellContents); + Debug.log(Debug.INFO, "YAHOO Found Formula" + cellContents); + } + + CellDescriptor cellDes = new CellDescriptor(row, column, ca, cellContents); + + try { + ws.putCell(cellDes); + } + catch (JMCException jmce) { + Debug.log(Debug.ERROR, "ws.putCell threw exception: " + jmce.getMessage()); + throw new IOException(jmce.getMessage()); + } + } + + + /** + * Set the width of the columns in the WorkBook. + * + * @param columnWidths An <code>IntArrayList</code> of column + * widths. + */ + public void setColumnWidths(IntArrayList columnWidths) throws IOException { + // Get the number of columns + int numColumns = columnWidths.size(); + + // Return if there are no columns in the listr + if (numColumns == 0) { + return; + } + + // Need to set the FORM_FLAGS_NONDEFAULT flag for the column widths + // to be used in MiniCalc + long format = JMCconstants.FORM_FLAGS_NONDEFAULT; + + CellAttributes ca = new CellAttributes(format); + + try { + for (int i = 0; i < numColumns; i++) { + // Get the column width in Palm pixels + int width = columnWidths.get(i) * pixelsPerChar; + + // Check limits on column width + if (width < minWidth) { + width = minWidth; + } else if (width > maxWidth) { + width = maxWidth; + } + + // Add the column descriptor to the WorkSheet + ws.putColumn(i + 1, width, ca); + } + } + catch (JMCException jmce) { + Debug.log(Debug.ERROR, "ws.putColumn threw exception: " + jmce.getMessage()); + throw new IOException(jmce.getMessage()); + } + } + + + /** + * This method sets the format of a cell to <i>string</i>. + * + * @param format The cell format-may already contain display info, + * such as alignment or font type. + * + * @return The updated format of the cell. + */ + private long setFormatString(long format) { + + format = clearCellFormatType(format); + + // Set format to generic, since MiniCalc does not have a string type. + format = format | JMCconstants.FF_FORMAT_GENERIC; + + return format; + } + + + /** + * This method sets the format of a cell to <i>floating point</i>. + * + * @param format The cell format. May already contain + * display info, such as alignment or + * font type. + * @param decimalPlaces The number of decimal places to + * set in the floating point number. + * + * @return The updated format of the cell. + */ + private long setFormatFloat(long format, int decimalPlaces) { + + format = clearCellFormatType(format); + + // Set format to floating point with correct number of decimal places + format = format | JMCconstants.FF_FORMAT_DECIMAL | decimalPlaces; + + return format; + } + + + /** + * This method sets the format of a cell to <i>time</i>. + * + * @param format The cell format-may already contain display info, + * such as alignment or font type. + * + * @return The updated format of the cell. + */ + private long setFormatTime(long format) { + + format = clearCellFormatType(format); + + // Set format to time. + format = format | JMCconstants.FF_FORMAT_TIME; + + return format; + } + + + /** + * This method sets the format of a cell to <i>date</i>. + * + * @param format The cell format-may already contain display info, + * such as alignment or font type. + * + * @return The updated format of the cell. + */ + private long setFormatDate(long format) { + + format = clearCellFormatType(format); + + // Set format to date. + format = format | JMCconstants.FF_FORMAT_DATE; + + return format; + } + + + /** + * This method sets the format of a cell to <i>currency</i>. + * + * @param format The cell format-may already contain + * display info, such as alignment or + * font type. + * @param decimalPlaces The number of decimal places to set. + * + * @return The updated format of the cell. + */ + private long setFormatCurrency(long format, int decimalPlaces) { + + format = clearCellFormatType(format); + + // Set format to Currency with correct number of decimal places + format = format | JMCconstants.FF_FORMAT_CURRENCY | decimalPlaces; + + return format; + } + + + /** + * This method sets the format of a cell to <i>boolean</i>. + * + * @param format The cell format-may already contain display info, + * such as alignment or font type. + * + * @return The updated format of the cell. + */ + private long setFormatBoolean(long format) { + + format = clearCellFormatType(format); + + // Set format to generic, since MiniCalc does not have a Boolean type. + format = format | JMCconstants.FF_FORMAT_GENERIC; + + return format; + } + + + /** + * This method sets the format of a cell to <i>percent</i>. + * + * @param format The cell format-may already contain + * display info, such as alignment or + * font type. + * @param decimalPlaces The number of decimal places to set. + * + * @return The updated format of the cell. + */ + private long setFormatPercent(long format, int decimalPlaces) { + + format = clearCellFormatType(format); + + // Set format to Percent with correct number of decimal places + format = format | JMCconstants.FF_FORMAT_PERCENT | decimalPlaces; + + return format; + } + + + /** + * This method clears out the format bits associated with + * the type of data (<i>float</i>, <i>time</i>, etc...) in + * a cell. + * + * @param format The original format for the cell. + * + * @return The updated cell format with the bits associated + * with the type of data (float, time, etc...) + * zeroed out. + */ + private long clearCellFormatType(long format) { + + // First 4 bits are for the number of decimal places + // bits 5-8 are for the data format (float, time, etc...) + + // Clear out first 8 bits + format = format & 0xFFFFFFFFFFFFFF00L; + + return format; + } + + + /** + * Set a cell's formatting options via a separately create + * <code>Format</code> object. + * + * @param row The row number of the cell to be changed. + * @param column The column number of the cell to be changed. + * @param fmt Object containing formatting settings for + * this cell. + */ + public void setCellFormat(int row, int column, Format fmt) { + } + + + /** + * Get the names of the sheets in the WorkBook. + * + * @param sheet The required sheet. + */ + public String getSheetName(int sheet) { + return wb.getWorksheet(sheet).getName(); + } + + + /* + * This method returns a MiniCalc style format from the + * <code>Format</code> object. + */ + private long getFormat(Format fmt) + { + String category = fmt.getCategory(); + + if (category.equalsIgnoreCase(OfficeConstants.CELLTYPE_BOOLEAN)) { + return setFormatBoolean(0); + } + else if (category.equalsIgnoreCase(OfficeConstants.CELLTYPE_CURRENCY)) { + return setFormatCurrency(0, fmt.getDecimalPlaces()); + } + else if (category.equalsIgnoreCase(OfficeConstants.CELLTYPE_DATE)) { + return setFormatDate(0); + } + else if (category.equalsIgnoreCase(OfficeConstants.CELLTYPE_FLOAT)) { + return setFormatFloat(0, fmt.getDecimalPlaces()); + } + else if (category.equalsIgnoreCase(OfficeConstants.CELLTYPE_PERCENT)) { + return setFormatPercent(0, fmt.getDecimalPlaces()); + } + else if (category.equalsIgnoreCase(OfficeConstants.CELLTYPE_STRING)) { + return setFormatString(0); + } + else if (category.equalsIgnoreCase(OfficeConstants.CELLTYPE_TIME)) { + return setFormatTime(0); + } + else { + // Should never get here, but just in case + System.out.println("XXXXX Formatting information not found"); + return 0; + } + } +} + diff --git a/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/PluginFactoryImpl.java b/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/PluginFactoryImpl.java new file mode 100644 index 000000000000..037347d4c44c --- /dev/null +++ b/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/PluginFactoryImpl.java @@ -0,0 +1,129 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.minicalc; + +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.DocumentSerializer; +import org.openoffice.xmerge.DocumentSerializerFactory; +import org.openoffice.xmerge.DocumentDeserializer; +import org.openoffice.xmerge.DocumentDeserializerFactory; +import org.openoffice.xmerge.DocumentMerger; +import org.openoffice.xmerge.ConverterCapabilities; +import org.openoffice.xmerge.converter.xml.sxc.DocumentMergerImpl; +import org.openoffice.xmerge.converter.xml.sxc.SxcPluginFactory; +import org.openoffice.xmerge.converter.palm.PalmDocument; +import org.openoffice.xmerge.util.registry.ConverterInfo; +import java.io.IOException; +import java.io.InputStream; + +/** + * <p>MiniCalc implementation of the <code>PluginFactory</code>. + * This encapsulates conversion of StarCalc XML format to and from + * MiniCalc format.</p> + * + * <p>The superclass produces a particular + * {@link org.openoffice.xmerge.Document Document} + * object, i.e. {@link + * org.openoffice.xmerge.converter.xml.sxc.SxcDocument + * SxcDocument} that the converters in this class works with. Thus, + * this class only implements the methods that produces the converters, + * i.e. {@link + * org.openoffice.xmerge.DocumentSerializer + * DocumentSerializer} and {@link + * org.openoffice.xmerge.DocumentDeserializer + * DocumentDeserializer}; + * as well as the {@link + * org.openoffice.xmerge.ConverterCapabilities + * ConverterCapabilities} object that is specific to this format + * conversion. That superclass also produces a {@link + * org.openoffice.xmerge.DocumentMerger DocumentMerger} + * object, i.e. {@link + * org.openoffice.xmerge.converter.xml.sxc.DocumentMergerImpl + * DocumentMergerImpl} which this class derives the functionality.</p> + */ +public final class PluginFactoryImpl extends SxcPluginFactory + implements DocumentDeserializerFactory, DocumentSerializerFactory { + + /** ConverterCapabilities object for this type of conversion. */ + private final static ConverterCapabilities converterCap = + new ConverterCapabilitiesImpl(); + + + public PluginFactoryImpl(ConverterInfo ci) { + super(ci); + } + + + /** + * Returns an instance of <code>DocumentSerializerImpl</code>, + * which is an implementation of <code>DocumentSerializer</code> + * interface. + * + * @param doc <code>Document</code> object to be + * converted/serialized. + * + * @return A <code>DocumentSerializerImpl</code> object. + */ + public DocumentSerializer createDocumentSerializer(Document doc) { + + return new SxcDocumentSerializerImpl(doc); + } + + + /** + * Returns an instance of <code>DocumentDeserializerImpl</code>, + * which is an implementation of <code>DocumentDeserializer</code> + * interface. + * + * @param cd <code>ConvertData</code> object for reading data + * which will be converted back to a + * <code>Document</code> object. + * + * @return A <code>DocumentDeserializerImpl</code> object. + */ + public DocumentDeserializer createDocumentDeserializer(ConvertData cd) { + + return new SxcDocumentDeserializerImpl(cd); + } + + + public Document createDeviceDocument(String name, InputStream is) + throws IOException { + + PalmDocument palmDoc = new PalmDocument(is); + return palmDoc; + } + + public DocumentMerger createDocumentMerger(Document doc) { + + DocumentMergerImpl merger = new DocumentMergerImpl(doc, converterCap); + return merger; + } +} + diff --git a/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/SxcDocumentDeserializerImpl.java b/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/SxcDocumentDeserializerImpl.java new file mode 100644 index 000000000000..61680e73f3a1 --- /dev/null +++ b/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/SxcDocumentDeserializerImpl.java @@ -0,0 +1,138 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.minicalc; + +import org.openoffice.xmerge.converter.xml.sxc.SxcDocumentDeserializer; +import org.openoffice.xmerge.converter.xml.sxc.SpreadsheetDecoder; +import org.openoffice.xmerge.converter.palm.PalmDB; +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.converter.palm.PalmDocument; + +import java.io.IOException; +import java.util.Enumeration; + +/** + * <p>MiniCalc implementation of <code>DocumentDeserializer</code> + * for the {@link + * org.openoffice.xmerge.converter.xml.sxc.minicalc.PluginFactoryImpl + * PluginFactoryImpl}.</p> + * + * <p>This converts a set of files in MiniCalc PDB format to a StarOffice DOM.</p> + * + * @author Mark Murnane + */ +public final class SxcDocumentDeserializerImpl extends SxcDocumentDeserializer { + + /** + * Creates new <code>SxcDocumentDeserializerImpl</code>. + * + * @param cd <code>ConvertData</code> Input data to convert. + */ + public SxcDocumentDeserializerImpl(ConvertData cd) { + super(cd); + } + + + /** + * This method will be implemented by concrete subclasses and will + * return an application-specific decoder. + * + * @param workbook The WorkBook name. + * @param worksheetNames An array of WorkSheet names. + * @param password The password. + * + * @return An application-specific <code>SpreadsheetDecoder</code>. + */ + public SpreadsheetDecoder createDecoder(String workbook, + String[] worksheetNames, String password) throws IOException { + + return new MinicalcDecoder(workbook, worksheetNames, password); + } + + + /** + * This method will return the name of the WorkBook from the + * <code>ConvertData</code>. Allows for situations where the + * WorkBook name differs from the PDB name. + * + * Implemented in the Deserializer as the Decoder's constructor + * requires a name. + * + * @param cd The <code>ConvertData</code>. + * + * @return The name of the WorkBook. + */ + protected String getWorkbookName(ConvertData cd) + throws IOException { + + Enumeration e = cd.getDocumentEnumeration(); + PalmDocument palmDoc = (PalmDocument) e.nextElement(); + String workbookName = palmDoc.getName(); + + // Search for "-", which separates workbook from worksheet + int end = workbookName.indexOf("-"); + + if (end > 0) { + workbookName = workbookName.substring(0, end); + } + + return workbookName; + } + + + /** + * This method will return an array of WorkSheet names from the + * <code>ConvertData</code>. + * + * @param cd The <code>ConvertData</code>. + * + * @return The name of the WorkSheet. + */ + protected String[] getWorksheetNames(ConvertData cd) + throws IOException { + int numberOfPDBs = cd.getNumDocuments(); + String worksheetName[] = new String[numberOfPDBs]; + int i=0; + Enumeration e = cd.getDocumentEnumeration(); + while (e.hasMoreElements()) { + PalmDocument palmDoc = (PalmDocument) e.nextElement(); + worksheetName[i] = palmDoc.getName(); + + // Search for the "-", which seperates workbook from worksheet + int start = worksheetName[i].indexOf("-"); + + if (start != -1) { + worksheetName[i] = worksheetName[i].substring(start + 1); + } + i++; + } + + return worksheetName; + } +} + diff --git a/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/SxcDocumentSerializerImpl.java b/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/SxcDocumentSerializerImpl.java new file mode 100644 index 000000000000..25ad6dda73f4 --- /dev/null +++ b/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/SxcDocumentSerializerImpl.java @@ -0,0 +1,141 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package org.openoffice.xmerge.converter.xml.sxc.minicalc; + +import java.awt.Color; + +import org.w3c.dom.NodeList; +import org.w3c.dom.Node; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Element; + +import java.io.IOException; + +import org.openoffice.xmerge.Document; +import org.openoffice.xmerge.ConvertData; +import org.openoffice.xmerge.ConvertException; +import org.openoffice.xmerge.converter.palm.PalmDB; +import org.openoffice.xmerge.converter.palm.Record; +import org.openoffice.xmerge.converter.palm.PalmDocument; + +import jmc.JMCconstants; + +import org.openoffice.xmerge.converter.xml.sxc.Format; +import org.openoffice.xmerge.converter.xml.sxc.SxcDocumentSerializer; + +/** + * <p>MiniCalc implementation of <code>SxcDocumentDeserializer</code> + * for the {@link + * org.openoffice.xmerge.converter.xml.sxc.minicalc.PluginFactoryImpl + * PluginFactoryImpl}.</p> + * + * <p>This converts StarOffice XML format to a set of files in + * MiniCalc PDB format.</p> + * + * @author Paul Rank + * @author Mark Murnane + */ +public final class SxcDocumentSerializerImpl extends SxcDocumentSerializer { + + + /** + * Constructor. + * + * @param document The <code>Document</code> to convert. + */ + public SxcDocumentSerializerImpl(Document document) { + super(document); + } + + + public ConvertData serialize() throws ConvertException, IOException { + + + // Get the server side document name. This value should not + // contain a path or the file extension. + String docName = sxcDoc.getName(); + + // TODO - get real values for password when implemnted in XML + // Passwords are not currently stored in StarCalc XML format. + String password = null; + + encoder = new MinicalcEncoder(docName, password); + + // get dom document + org.w3c.dom.Document domDoc = sxcDoc.getContentDOM(); + + // Traverse to the office:body element. + // There should only be one. + NodeList list = domDoc.getElementsByTagName(TAG_OFFICE_BODY); + int len = list.getLength(); + + if (len > 0) { + Node node = list.item(0); + traverseBody(node); + } + + // Get the number of sheets in the workbook + // This will equal the number of PDBs we need + ConvertData cd = new ConvertData(); + int numSheets = encoder.getNumberOfSheets(); + + for (int i = 0; i < numSheets; i++) { + + // Get records for sheet i + Record records[] = ((MinicalcEncoder) encoder).getRecords(i); + + // Get the sheet name for sheet i + String fullSheetName = new String(docName + + "-" + + encoder.getSheetName(i)); + + // Create a PalmDB object + PalmDocument palmDoc = new PalmDocument(fullSheetName, + MinicalcConstants.CREATOR_ID, + MinicalcConstants.TYPE_ID, JMCconstants.AppVersion, + PalmDB.PDB_HEADER_ATTR_BACKUP, records); + + cd.addDocument(palmDoc); + } + + + // OutputStream os = new FileOutputStream(docName); + + //pdbSet.write(os); + //os.flush(); + + //ConvertDataEntry cde = new ConvertDataOutputStream(os, docName); + //cd.addCDE(cde); + + return cd; + } + + + +} + diff --git a/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/package.html b/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/package.html new file mode 100644 index 000000000000..2adb11ed36d4 --- /dev/null +++ b/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/package.html @@ -0,0 +1,53 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- + #************************************************************************* + # + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + + Copyright 2000, 2010 Oracle and/or its affiliates. + + OpenOffice.org - a multi-platform office productivity suite + + This file is part of OpenOffice.org. + + OpenOffice.org is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + OpenOffice.org 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 version 3 for more details + (a copy is included in the LICENSE file that accompanied this code). + + You should have received a copy of the GNU Lesser General Public License + version 3 along with OpenOffice.org. If not, see + <http://www.openoffice.org/license.html> + for a copy of the LGPLv3 License. + + #************************************************************************* + --> +<html> +<head> +<title>org.openoffice.xmerge.converter.xml.sxc.minicalc package</title> +</head> + +<body bgcolor="white"> + +<p>Provides the tools for doing the conversion of StarWriter XML to +and from MiniCalc format.</p> + +<p>It follows the {@link org.openoffice.xmerge} framework for the conversion process.</p> + +<p>Since it converts to/from a Palm application format, these converters +follow the <a href=../../../../converter/palm/package-summary.html#streamformat> +PalmDB stream format</a> for writing out to the Palm sync client or reading +in from the Palm sync client.</p> + +<p>Note that <code>PluginFactoryImpl</code> also provides a +<code>DocumentMerger</code> object, i.e. {@link org.openoffice.xmerge.converter.xml.sxw.aportisdoc.DocumentMergerImpl DocumentMergerImpl}. +This functionality was derived from its superclass +{@link org.openoffice.xmerge.converter.xml.sxw.SxwPluginFactory SxwPluginFactory}.</p> + +</body> +</html> |