/* Copyright 2011 Toby D. Rule
This file is part of CompPad, an OpenOffice extension to provide live
mathematical and engineering calculations within a Writer document.
CompPad is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CompPad 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with CompPad. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.CompPad.OOO;
import com.CompPad.model.Expression2;
import com.sun.star.beans.XPropertySet;
import com.sun.star.container.XEnumeration;
import com.sun.star.container.XEnumerationAccess;
import com.sun.star.container.XIndexAccess;
import com.sun.star.container.XNameAccess;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.table.XCell;
import com.sun.star.table.XTable;
import com.sun.star.text.XText;
import com.sun.star.text.XTextCursor;
import com.sun.star.text.XTextDocument;
import com.sun.star.text.XTextRange;
import com.sun.star.text.XTextRangeCompare;
import com.sun.star.text.XTextSection;
import com.sun.star.text.XTextTable;
import com.sun.star.text.XTextTableCursor;
import com.sun.star.text.XTextTablesSupplier;
import com.sun.star.uno.Any;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.util.XSortable;
import groovy.lang.PropertyValue;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* This interface will provide services common for elements of a CompPad
* document in openoffice
* @author brenda
*/
/* it might make more sense to implement this class as abstract! */
public class OOOElement implements Comparable {
public XTextDocument xTextDocument;
private Class[] valueTypes={};
/* Empty list since it doesn't handle anything right now */
public int compareTo(Object exp2) {
Logger.getLogger("com.CompPad").log(Level.FINE,"compareTo");
/* Overrides Comparable.compareTo */
/* Need to throw an exception when exp2 cannot be cast to OOOElement*/
int retval=0;
try{
XTextRange range1 = this.getTextRange();
XTextRange range2 = ((OOOElement)exp2).getTextRange();
XText text1 = range1.getText();
XText text2 = range2.getText();
String cellName1 = getCellName(range1);
String cellName2 = getCellName(range2);
XTextTable table1=getTable(range1);
XTextTable table2=getTable(range2);
Logger.getLogger("com.CompPad").log(Level.FINE,"range1 "+range1+" range2 "+range2);
Logger.getLogger("com.CompPad").log(Level.FINE,"cellName1 "+cellName1+" cellName2 "+cellName2);
Logger.getLogger("com.CompPad").log(Level.FINE,"table1 "+table1+" table2 "+table2);
if (text1 == text2){
// the formulas are in different parts of the same XText,
// either the main XText or else in the same cell in a table.
Logger.getLogger("com.CompPad").log(Level.FINE,"text1 "+range1.getText()+" text2 "+range2.getText());
Logger.getLogger("com.CompPad").log(Level.FINE,"range1 "+range1+" range2 "+range2);
XTextRangeCompare xTRC = (XTextRangeCompare)
UnoRuntime.queryInterface(XTextRangeCompare.class,
range1.getText());
retval = xTRC.compareRegionStarts(range2, range1);
Logger.getLogger("com.CompPad").log(Level.FINE, "retval = "+retval);
}
else if(table1 != null && table1 == table2)
{
// formulas are in same table but not the same cell.
// Compare cell names.
retval = compareCellName(cellName1,cellName2);
}
else if (table1 != null || table2 != null){
// one of the formulas is in a table. Get the range of the table
if (table1!=null){
range1 = getTableRange(table1);
}
if (table2!=null){
range2 = getTableRange(table2);
}
XTextRangeCompare xTRC = (XTextRangeCompare)
UnoRuntime.queryInterface(XTextRangeCompare.class,
range1.getText());
retval = xTRC.compareRegionEnds(range2, range1);
Logger.getLogger("com.CompPad").log(Level.FINE, " table1 != null || table2 != null , retval = "+retval);
}
else{
throw (new Exception("Error comparing formula positions!"));
}
} catch (java.lang.Exception ex){
Logger.getLogger(Expression2.class.getName()).log(Level.SEVERE, null, ex);
Logger.getLogger("com.CompPad").log(Level.FINE," BLAHHH!!");
}
return retval;
}
private XTextRange getTableRange(XTextTable table) throws Exception{
XTextRange retval = null;
// table anchors don't have a position in the text!!!!
// So we have to iterate through text contents to find this table..
// The idea for this code came from:
// http://www.oooforum.org/forum/viewtopic.phtml?t=60451
XTextRange textRange = null;
XEnumerationAccess xParaAccess = (XEnumerationAccess) UnoRuntime.queryInterface(
XEnumerationAccess.class, table.getAnchor().getText());
XEnumeration xParaEnum = xParaAccess.createEnumeration();
while (retval == null && xParaEnum.hasMoreElements()){
Object elt = xParaEnum.nextElement();
XServiceInfo xInfo = (XServiceInfo) UnoRuntime.queryInterface(
XServiceInfo.class, elt);
if (xInfo.supportsService("com.sun.star.text.TextTable")) {
XTextTable xTable = (XTextTable) UnoRuntime.queryInterface(
XTextTable.class, elt);
if (xTable == table) {
if (textRange != null){
// elt = xParaEnum.nextElement();
// textRange = (XTextRange) UnoRuntime.queryInterface(
// XTextRange.class, elt);
retval = textRange.getEnd();
}
else {
// get the beginning of the xtext
retval = table.getAnchor().getText().getStart();
}
}
}
else{
textRange = (XTextRange) UnoRuntime.queryInterface(
XTextRange.class, elt);
}
}
return retval;
}
private String getCellName(XTextRange range)throws java.lang.Exception{
XCell cell = UnoRuntime.queryInterface(XCell.class,range.getText());
String retval = null;
if (cell!=null){
retval = (String) ((XPropertySet)UnoRuntime
.queryInterface(XPropertySet.class,cell))
.getPropertyValue("CellName");
}
return retval;
}
private Integer compareCellName(String s1, String s2){
Integer retval = null;
Integer row1 = Integer.valueOf(s1.replaceFirst("\\D+", ""));
Integer row2 = Integer.valueOf(s2.replaceFirst("\\D+", ""));
String col1 = s1.replaceFirst("\\d+", "");
String col2 = s2.replaceFirst("\\d+", "");
if (row1.equals(row2)){
retval = col1.compareTo(col2);
Logger.getLogger("com.CompPad").log(Level.FINE, " Comparing columns "+col1 + col2 + retval);
}
else{
retval = row1-row2;
}
Logger.getLogger("com.CompPad").log(Level.FINE," compareCellName "+s1 + " " + s2 + " "+ col1 +" "+ col2 + row1 + row2 + retval);
return retval;
}
private XTextTable getTable(XTextRange range) throws java.lang.Exception{
// Iterate through tables and find a table with a
// cell by that name that contains that cell
XTextTable retval= null;
XCell cell = UnoRuntime.queryInterface(XCell.class,range.getText());
if (cell!=null){
String cellname = (String) ((XPropertySet)UnoRuntime
.queryInterface(XPropertySet.class,cell))
.getPropertyValue("CellName");
XTextTablesSupplier tableSupplier = UnoRuntime.queryInterface(XTextTablesSupplier.class, xTextDocument);
XNameAccess tablenames = tableSupplier.getTextTables();
XIndexAccess tableindex = (XIndexAccess) UnoRuntime.queryInterface(XIndexAccess.class, tablenames);
Logger.getLogger("com.CompPad").log(Level.FINE,"tableindex "+tableindex);
for (int i=0; i < tableindex.getCount(); i++){
XTextTable table = (XTextTable)UnoRuntime.queryInterface(XTextTable.class,tableindex.getByIndex(i));
XCell tcell = table.getCellByName(cellname);
if (tcell==cell){
// this is the cell we've been looking for!
Logger.getLogger("com.CompPad").log(Level.FINE,"FOUND!");
// get the xTextRange from the xTextContent of the xTextTable
retval = table;
}
}
}
return retval;
}
public XTextCursor getTextCursor() throws Exception{
throw new java.lang.Exception("Not Implemented");
}
public XTextRange getTextRange() throws Exception{
throw new java.lang.Exception("Not Implemented");
}
public String getName() throws Exception {
throw new java.lang.Exception("Not Implemented");
}
public void dispose() throws Exception{
throw new java.lang.Exception("Must be overridden in subclass");
}
public void setDependsOn(OOOExpression arg) throws Exception{
throw new java.lang.Exception("Not Implemented");
}
public boolean canHandle(Object e) throws Exception{
throw new java.lang.Exception("Not Implemented");
}
public void handle(Object e) throws Exception{
throw new java.lang.Exception("Not Implemented");
}
}