summaryrefslogtreecommitdiff
path: root/xmerge/source/minicalc
diff options
context:
space:
mode:
authorJens-Heiner Rechtien <hr@openoffice.org>2005-10-24 15:08:58 +0000
committerJens-Heiner Rechtien <hr@openoffice.org>2005-10-24 15:08:58 +0000
commit05ed6361e6b451577d65d4fc2ceeaaf2c467773c (patch)
tree01b15e404b3d98e54bf402d8d18d124dfe92e642 /xmerge/source/minicalc
parentfa4eb446a72e41003874a71c43b595b6c1d7cfbb (diff)
INTEGRATION: CWS lo8 (1.1.2); FILE ADDED
2005/06/08 16:27:26 lo 1.1.2.1: restructuring of project and fix for #i44847#
Diffstat (limited to 'xmerge/source/minicalc')
-rw-r--r--xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcDataString.java573
-rw-r--r--xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcDecoder.java772
2 files changed, 1345 insertions, 0 deletions
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..fa90e2ef15b0
--- /dev/null
+++ b/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcDataString.java
@@ -0,0 +1,573 @@
+/************************************************************************
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+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..016933959e44
--- /dev/null
+++ b/xmerge/source/minicalc/java/org/openoffice/xmerge/converter/xml/sxc/minicalc/MinicalcDecoder.java
@@ -0,0 +1,772 @@
+/************************************************************************
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+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());
+ // e.printStackTrace();
+
+ }
+ }
+
+
+ /**
+ * 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());
+ // e.printStackTrace();
+
+ }
+ }
+
+
+ /**
+ * 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());
+ // e.printStackTrace();
+
+ }
+
+ 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
+ }
+}
+