/*********************************************************************
*
* Copyright (C) 2004 Andrew Khan
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* 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
***************************************************************************/
package jxl.biff;
import java.util.Collection;
import jxl.common.Assert;
import jxl.common.Logger;
import jxl.CellReferenceHelper;
import jxl.Range;
import jxl.biff.drawing.ComboBox;
import jxl.biff.drawing.Comment;
import jxl.write.biff.CellValue;
/**
* Container for any additional cell features
*/
public class BaseCellFeatures
{
/**
* The logger
*/
public static Logger logger = Logger.getLogger(BaseCellFeatures.class);
/**
* The comment
*/
private String comment;
/**
* The comment width in cells
*/
private double commentWidth;
/**
* The comment height in cells
*/
private double commentHeight;
/**
* A handle to the drawing object
*/
private Comment commentDrawing;
/**
* A handle to the combo box object
*/
private ComboBox comboBox;
/**
* The data validation settings
*/
private DataValiditySettingsRecord validationSettings;
/**
* The DV Parser used to contain the validation details
*/
private DVParser dvParser;
/**
* Indicates whether a drop down is required
*/
private boolean dropDown;
/**
* Indicates whether this cell features has data validation
*/
private boolean dataValidation;
/**
* The cell to which this is attached, and which may need to be notified
*/
private CellValue writableCell;
// Constants
private final static double defaultCommentWidth = 3;
private final static double defaultCommentHeight = 4;
// Validation conditions
protected static class ValidationCondition
{
private DVParser.Condition condition;
private static ValidationCondition[] types = new ValidationCondition[0];
ValidationCondition(DVParser.Condition c)
{
condition = c;
ValidationCondition[] oldtypes = types;
types = new ValidationCondition[oldtypes.length+1];
System.arraycopy(oldtypes, 0, types, 0, oldtypes.length);
types[oldtypes.length] = this;
}
public DVParser.Condition getCondition()
{
return condition;
}
}
public static final ValidationCondition BETWEEN =
new ValidationCondition(DVParser.BETWEEN);
public static final ValidationCondition NOT_BETWEEN =
new ValidationCondition(DVParser.NOT_BETWEEN);
public static final ValidationCondition EQUAL =
new ValidationCondition(DVParser.EQUAL);
public static final ValidationCondition NOT_EQUAL =
new ValidationCondition(DVParser.NOT_EQUAL);
public static final ValidationCondition GREATER_THAN =
new ValidationCondition(DVParser.GREATER_THAN);
public static final ValidationCondition LESS_THAN =
new ValidationCondition(DVParser.LESS_THAN);
public static final ValidationCondition GREATER_EQUAL =
new ValidationCondition(DVParser.GREATER_EQUAL);
public static final ValidationCondition LESS_EQUAL =
new ValidationCondition(DVParser.LESS_EQUAL);
/**
* Constructor
*/
protected BaseCellFeatures()
{
}
/**
* Copy constructor
*
* @param the cell to copy
*/
public BaseCellFeatures(BaseCellFeatures cf)
{
// The comment stuff
comment = cf.comment;
commentWidth = cf.commentWidth;
commentHeight = cf.commentHeight;
// The data validation stuff.
dropDown = cf.dropDown;
dataValidation = cf.dataValidation;
validationSettings = cf.validationSettings; // ?
if (cf.dvParser != null)
{
dvParser = new DVParser(cf.dvParser);
}
}
/**
* Accessor for the cell comment
*/
protected String getComment()
{
return comment;
}
/**
* Accessor for the comment width
*/
public double getCommentWidth()
{
return commentWidth;
}
/**
* Accessor for the comment height
*/
public double getCommentHeight()
{
return commentHeight;
}
/**
* Called by the cell when the features are added
*
* @param wc the writable cell
*/
public final void setWritableCell(CellValue wc)
{
writableCell = wc;
}
/**
* Internal method to set the cell comment. Used when reading
*/
public void setReadComment(String s, double w, double h)
{
comment = s;
commentWidth = w;
commentHeight = h;
}
/**
* Internal method to set the data validation. Used when reading
*/
public void setValidationSettings(DataValiditySettingsRecord dvsr)
{
Assert.verify(dvsr != null);
validationSettings = dvsr;
dataValidation = true;
}
/**
* Sets the cell comment
*
* @param s the comment
*/
public void setComment(String s)
{
setComment(s, defaultCommentWidth, defaultCommentHeight);
}
/**
* Sets the cell comment
*
* @param s the comment
* @param height the height of the comment box in cells
* @param width the width of the comment box in cells
*/
public void setComment(String s, double width, double height)
{
comment = s;
commentWidth = width;
commentHeight = height;
if (commentDrawing != null)
{
commentDrawing.setCommentText(s);
commentDrawing.setWidth(width);
commentDrawing.setWidth(height);
// commentDrawing is set up when trying to modify a copied cell
}
}
/**
* Removes the cell comment, if present
*/
public void removeComment()
{
// Set the comment string to be empty
comment = null;
// Remove the drawing from the drawing group
if (commentDrawing != null)
{
// do not call DrawingGroup.remove() because comments are not present
// on the Workbook DrawingGroup record
writableCell.removeComment(commentDrawing);
commentDrawing = null;
}
}
/**
* Public function which removes any data validation, if present
*/
public void removeDataValidation()
{
if (!dataValidation)
{
return;
}
// If the data validation is shared, then generate a warning
DVParser dvp = getDVParser();
if (dvp.extendedCellsValidation())
{
logger.warn("Cannot remove data validation from " +
CellReferenceHelper.getCellReference(writableCell) +
" as it is part of the shared reference " +
CellReferenceHelper.getCellReference(dvp.getFirstColumn(),
dvp.getFirstRow()) +
"-" +
CellReferenceHelper.getCellReference(dvp.getLastColumn(),
dvp.getLastRow()));
return;
}
// Remove the validation from the WritableSheet object if present
writableCell.removeDataValidation();
clearValidationSettings();
}
/**
* Internal function which removes any data validation, including
* shared ones, if present. This is called from WritableSheetImpl
* in response to a call to removeDataValidation
*/
public void removeSharedDataValidation()
{
if (!dataValidation)
{
return;
}
// Remove the validation from the WritableSheet object if present
writableCell.removeDataValidation();
clearValidationSettings();
}
/**
* Sets the comment drawing object
*/
public final void setCommentDrawing(Comment c)
{
commentDrawing = c;
}
/**
* Accessor for the comment drawing
*/
public final Comment getCommentDrawing()
{
return commentDrawing;
}
/**
* Gets the data validation list as a formula. Used only when reading
*
* @return the validation formula as a list
*/
public String getDataValidationList()
{
if (validationSettings == null)
{
return null;
}
return validationSettings.getValidationFormula();
}
/**
* The list of items to validate for this cell. For each object in the
* collection, the toString() method will be called and the data entered
* will be validated against that string
*
* @param c the list of valid values
*/
public void setDataValidationList(Collection c)
{
if (dataValidation && getDVParser().extendedCellsValidation())
{
logger.warn("Cannot set data validation on " +
CellReferenceHelper.getCellReference(writableCell) +
" as it is part of a shared data validation");
return;
}
clearValidationSettings();
dvParser = new DVParser(c);
dropDown = true;
dataValidation = true;
}
/**
* The list of items to validate for this cell in the form of a cell range.
*
* @param c the list of valid values
*/
public void setDataValidationRange(int col1, int r1, int col2, int r2)
{
if (dataValidation && getDVParser().extendedCellsValidation())
{
logger.warn("Cannot set data validation on " +
CellReferenceHelper.getCellReference(writableCell) +
" as it is part of a shared data validation");
return;
}
clearValidationSettings();
dvParser = new DVParser(col1, r1, col2, r2);
dropDown = true;
dataValidation = true;
}
/**
* Sets the data validation based upon a named range
*/
public void setDataValidationRange(String namedRange)
{
if (dataValidation && getDVParser().extendedCellsValidation())
{
logger.warn("Cannot set data validation on " +
CellReferenceHelper.getCellReference(writableCell) +
" as it is part of a shared data validation");
return;
}
clearValidationSettings();
dvParser = new DVParser(namedRange);
dropDown = true;
dataValidation = true;
}
/**
* Sets the data validation based upon a numerical condition
*/
public void setNumberValidation(double val, ValidationCondition c)
{
if (dataValidation && getDVParser().extendedCellsValidation())
{
logger.warn("Cannot set data validation on " +
CellReferenceHelper.getCellReference(writableCell) +
" as it is part of a shared data validation");
return;
}
clearValidationSettings();
dvParser = new DVParser(val, Double.NaN, c.getCondition());
dropDown = false;
dataValidation = true;
}
public void setNumberValidation(double val1, double val2,
ValidationCondition c)
{
if (dataValidation && getDVParser().extendedCellsValidation())
{
logger.warn("Cannot set data validation on " +
CellReferenceHelper.getCellReference(writableCell) +
" as it is part of a shared data validation");
return;
}
clearValidationSettings();
dvParser = new DVParser(val1, val2, c.getCondition());
dropDown = false;
dataValidation = true;
}
/**
* Accessor for the data validation
*
* @return TRUE if this has a data validation associated with it,
FALSE otherwise
*/
public boolean hasDataValidation()
{
return dataValidation;
}
/**
* Clears out any existing validation settings
*/
private void clearValidationSettings()
{
validationSettings = null;
dvParser = null;
dropDown = false;
comboBox = null;
dataValidation = false;
}
/**
* Accessor for whether a drop down is required
*
* @return TRUE if this requires a drop down, FALSE otherwise
*/
public boolean hasDropDown()
{
return dropDown;
}
/**
* Sets the combo box drawing object for list validations
*
* @param cb the combo box
*/
public void setComboBox(ComboBox cb)
{
comboBox = cb;
}
/**
* Gets the dv parser
*/
public DVParser getDVParser()
{
// straightforward - this was created as a writable cell
if (dvParser != null)
{
return dvParser;
}
// this was copied from a readable cell, and then copied again
if (validationSettings != null)
{
dvParser = new DVParser(validationSettings.getDVParser());
return dvParser;
}
return null; // keep the compiler happy
}
/**
* Use the same data validation logic as the specified cell features
*
* @param cf the data validation to reuse
*/
public void shareDataValidation(BaseCellFeatures source)
{
if (dataValidation)
{
logger.warn("Attempting to share a data validation on cell " +
CellReferenceHelper.getCellReference(writableCell) +
" which already has a data validation");
return;
}
clearValidationSettings();
dvParser = source.getDVParser();
validationSettings = null;
dataValidation = true;
dropDown = source.dropDown;
comboBox = source.comboBox;
}
/**
* Gets the range of cells to which the data validation applies. If the
* validation applies to just this cell, this will be reflected in the
* returned range
*
* @return the range to which the same validation extends, or NULL if this
* cell doesn't have a validation
*/
public Range getSharedDataValidationRange()
{
if (!dataValidation)
{
return null;
}
DVParser dvp = getDVParser();
return new SheetRangeImpl(writableCell.getSheet(),
dvp.getFirstColumn(),
dvp.getFirstRow(),
dvp.getLastColumn(),
dvp.getLastRow());
}
}
|