/* ========================
* JSynoptic : a free Synoptic editor
* ========================
*
* Project Info: http://jsynoptic.sourceforge.net/index.html
*
* This program 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 program 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
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2001-2003, by :
* Corporate:
* Astrium SAS
* EADS CRC
* Individual:
* Nicolas Brodu
*
* $Id: HistoryShape.java,v 1.26 2008/09/05 12:23:22 ogor Exp $
*
* Changes
* -------
* 16-Oct-2003 : Initial version (NB);
*
*/
package jsynoptic.builtin;
import java.util.Iterator;
import java.util.ResourceBundle;
import java.util.Vector;
import javax.swing.undo.CompoundEdit;
import jsynoptic.builtin.ui.HistoryPropertiesPanel;
import simtools.data.DataException;
import simtools.data.DataInfo;
import simtools.data.DataSource;
import simtools.shapes.AbstractShape;
import simtools.ui.JPropertiesPanel;
import simtools.ui.ResourceFinder;
/**
* History shapes keep the previous values of a data source and display them in
* a text array
*
* @deprecated Use HistoryTextShape instead
*/
public class HistoryShape extends TextArrayShape {
static final long serialVersionUID = 5471834643284146991L;
public static ResourceBundle resources = ResourceFinder.get(HistoryShape.class, TextArrayShape.resources);
/**
* Build an History shape with the given history size (number of time values
* to retain). The width argument is the array width, the height one is the
* height of <b>one</b> cell.
*
* @param histSize
* The number of time values to retain
* @param width
* The array width @ param height The height of one cell in the array
*/
public HistoryShape(int histSize, int width, int cellHeight) {
if (cellHeight < TextShape.MIN_HEIGHT) {
cellHeight = TextShape.MIN_HEIGHT;
}
cells = new Vector();
for (int i = 0; i < histSize; ++i) {
HookedTextShape ts = createHookedTextShape(Builtin.resources.getString("Text"), width, cellHeight);
ts.owner = this;
ts.setAnchor(_ox, _oy + (i + 1) * cellHeight);
cells.add(ts);
}
// Set witdh
if (cells.size() > 0) {
_w = ((HookedTextShape) cells.get(0)).getBounds().width;
}
if (_w < TextShape.MIN_WIDTH) {
_w = TextShape.MIN_WIDTH;
}
// Set height
_h = cellHeight * histSize;
_y = _h;
}
/**
* By overwriting this method, it is possible to create different kind of history cells
* @param name
* @param width
* @param height
* @return a text shape belonging to history
*/
protected HookedTextShape createHookedTextShape(String text, int width, int height) {
return new HookedTextShape(text, width, height);
}
public String[] getActions(double x, double y, Object o, int context) {
if (context == MOUSE_OVER_CONTEXT) {
return null;
}
if (context == MOUSE_OUT_CONTEXT) {
return null;
}
if (context == MOUSE_PRESSED_CONTEXT) {
return null;
}
if (context == EDITOR_CONTEXT) {
}
Vector v = new Vector();
v.add(resources.getString("Properties..."));
if (o instanceof DataSource) {
v.add(resources.getString("SetSource"));
}
return (String[]) v.toArray(new String[v.size()]);
}
/*
* (non-Javadoc)
*
* @see jsynoptic.builtin.Abstract1DShape#createPanel()
*/
public JPropertiesPanel createPanel() {
return new HistoryPropertiesPanel(Builtin.resources.getString("History"));
}
/*
* (non-Javadoc)
*
* @see jsynoptic.base.ContextualActionProvider#doAction(double, double,
* java.lang.Object, java.lang.String)
*/
public boolean doAction(double x, double y, Object o, String action, CompoundEdit undoableEdit) {
if (action.equals(resources.getString("SetSource"))) {
return addDataSource((DataSource) o);
}
if (action.equals(resources.getString("Properties..."))) {
return super.doAction(x, y, o, action, undoableEdit);
}
return false;
}
/*
* (non-Javadoc)
*
* @see jsynoptic.base.ContextualActionProvider#canDoAction(double, double,
* java.lang.Object, java.lang.String, int)
*/
public boolean canDoAction(double x, double y, Object o, String action, int context) {
return true;
}
protected void initWithLastDataSourceValues() {
// Set cell text
HookedTextShape ts0 = (HookedTextShape) cells.get(0);
DataSource source = ts0.source;
if (source != null) {
try {
long dsIndex = source.getLastIndex();
for (int i = 0; i < cells.size(); i++) {
// Get text value from fisrt cell properties
String text = "";
if (ts0.displayDsName.booleanValue()) {
String name = DataInfo.getLabel(source);
if ((name != null) && !name.equals("")) {
text += name;
if (ts0.displayDsValue.booleanValue()) {
text += "=";
}
}
}
try {
if (ts0.displayDsValue.booleanValue()) {
text += ts0.formatSourceValue(source.getValue(dsIndex));
}
} catch (DataException e) {
text += TextShape.resources.getString("NoValue");
}
if (ts0.displayDsUnit.booleanValue()) {
String unit = DataInfo.getUnit(source);
if ((unit != null) && !unit.equals("")) {
text += " [" + unit + "]";
}
}
if (ts0.displayDsComments.booleanValue()) {
String comments = DataInfo.getComment(source);
if ((comments != null) && !comments.equals("")) {
text += " (" + comments + ")";
}
}
// Set hookedTextShape value
HookedTextShape ts = (HookedTextShape) cells.get(i);
ts.setPropertyValue("TEXT", text);
dsIndex--;
}
} catch (DataException e) {
// data source doesn't hold dsIndex values
}
}
}
/*
* (non-Javadoc)
*
* @see jsynoptic.builtin.TextArrayShape#setCells(java.util.Vector)
*/
public void setCells(Vector cellsProperties) {
if (cellsProperties.size() > 0) {
Vector cellProperties = (Vector) cellsProperties.get(0);
_w = 0;
for (int j = 0; j < cellProperties.size(); j++) {
Object[] property = (Object[]) cellProperties.get(j);
String pname = (String) property[0];
Object value = property[1];
if (!pname.equalsIgnoreCase("TEXT")) {
// Set properties to all cells
for (int i = 0; i < cells.size(); i++) {
HookedTextShape ts = (HookedTextShape) cells.get(i);
ts.setPropertyValue(pname, value);
// Update history width only when cell width is higther
int width = ts.getBounds().width;
if (width > _w) {
_w = width;
}
}
}
}
initWithLastDataSourceValues();
positionCells();
notifyChange();
}
}
/**
* Override methods called when data source change. => the first cell
* listens to data source Changes are propagated.
*/
public static class HookedTextShape extends TextShape {
static final long serialVersionUID = 1319437895774180799L;
protected transient HistoryShape owner;
public HookedTextShape(String text, int width, int height) {
super(text, width, height);
owner = null;
}
protected void propagate() {
TextShape tso = (TextShape) owner.cells.lastElement();
for (int i = owner.cells.size() - 1; i > 0; i--) {
TextShape tsn = (TextShape) owner.cells.get(i - 1);
tso.text = tsn.text;
tso.drawColor = tsn.drawColor;
tso.drawDynamicColor = tsn.drawDynamicColor;
tso.fillColor = tsn.fillColor;
tso.fillDynamicColor = tsn.fillDynamicColor;
tso.textColor = tsn.textColor;
tso.textDynamicColor = tsn.textDynamicColor;
tso.baseline = tsn.baseline;
tso.currentFont = tsn.currentFont;
tso = tsn;
}
}
/*
* (non-Javadoc)
*
* @see simtools.data.EndNotificationListener#notificationEnd(java.lang.Object)
*/
public void notificationEnd(Object referer) {
if ((owner != null) && equals(owner.cells.get(0))) {
propagate(); // whatever happens, duplicate values if values
// are the same
super.notificationEnd(referer);
owner.notificationEnd(referer);
}
}
}
/*
* (non-Javadoc)
*
* @see simtools.data.EndNotificationListener#notificationEnd(java.lang.Object)
*/
public void notificationEnd(Object referer) {
notifyChange(getBounds()); // propagation is done each time even is
// there is no change
}
/*
* (non-Javadoc)
*
* @see simtools.shapes.AbstractShape#cloneShape()
*/
protected AbstractShape cloneShape() {
HistoryShape clone = (HistoryShape) super.cloneShape();
// Override parent's mess => we need only one listener
for (Iterator it = clone.cells.iterator(); it.hasNext();) {
HookedTextShape ts = (HookedTextShape) it.next();
ts.owner = clone;
ts.setDelegateEndNotificationListener(ts);
}
// if (clone.cells.size()>0)
// ((HookedTextShape)clone.cells.get(0)).setDelegateEndNotificationListener(clone);
return clone;
}
// Restore unique font at de-serialization.
private void readObject(java.io.ObjectInputStream in) throws java.lang.ClassNotFoundException, java.io.IOException {
in.defaultReadObject();
// Override parent's mess => we need only one listener
for (Iterator it = cells.iterator(); it.hasNext();) {
HookedTextShape ts = (HookedTextShape) it.next();
ts.owner = this;
ts.setDelegateEndNotificationListener(ts);
}
initWithLastDataSourceValues();
}
/*
* (non-Javadoc)
*
* @see jsynoptic.base.DataSourceConsumer#addDataSource(simtools.data.DataSource)
*/
public boolean addDataSource(DataSource d) {
HookedTextShape ts = (HookedTextShape) cells.get(0);
ts.setSource(d);
initWithLastDataSourceValues();
notifyChange();
return true;
}
/* (non-Javadoc)
* @see simtools.shapes.AbstractShape#subscribeToDataNotifications()
*/
public void processShapeRestoring(){
HookedTextShape ts = (HookedTextShape) cells.get(0);
ts.processShapeRestoring();
super.processShapeRestoring();
}
/* (non-Javadoc)
* @see simtools.shapes.AbstractShape#unsubscribeToDataNotifications()
*/
public void processShapeRemoving(){
HookedTextShape ts = (HookedTextShape) cells.get(0);
ts.processShapeRemoving();
super.processShapeRemoving();
}
public void setPropertyValue(String name, Object value) {
if (name.equalsIgnoreCase("HISTORY_SIZE")) {
if (value instanceof Integer) {
int histSize = ((Integer) value).intValue();
int oldSize = cells.size();
if ((histSize >= 0) && (histSize != oldSize)) {
int cellHeight = cells.size() == 0 ? TextShape.MIN_HEIGHT : _h / cells.size();
if (cellHeight < TextShape.MIN_HEIGHT) {
cellHeight = TextShape.MIN_HEIGHT;
}
if (oldSize > histSize) {
for (int i = oldSize; i > histSize; i--) {
cells.remove(i - 1);
}
} else {
for (int i = oldSize; i < histSize; i++) {
HookedTextShape ts = createHookedTextShape(Builtin.resources.getString("Text"), _w,
cellHeight);
ts.owner = this;
ts.setAnchor(_ox, _oy + (i + 1) * cellHeight);
cells.add(ts);
}
}
_h = cellHeight * histSize;
_y = _h;
}
}
} else {
super.setPropertyValue(name, value);
}
}
public String[] getPropertyNames() {
if (_propertyNames == null) {
_propertyNames = new HistoryShape.HistoryShapePropertiesNames().getPropertyNames();
}
return _propertyNames;
}
public Object getPropertyValue(String name) {
Object res;
if (name.equalsIgnoreCase("HISTORY_SIZE")) {
res = new Integer(cells.size());
} else if (name.equalsIgnoreCase("TEXT_ARRAY_CELL_LIST")) {
Vector cellsProperties = new Vector();
if (cells.size() > 0) {
HookedTextShape textShape = (HookedTextShape) cells.get(0);
Vector cellProperties = new Vector();
String[] props = textShape.getPropertyNames();
if (props != null) {
for (int j = 0; j < props.length; j++) {
// Each property has a name and a value
Object[] property = new Object[2];
String pname = props[j];
Object value = textShape.getPropertyValue(pname);
property[0] = pname;
property[1] = value;
cellProperties.add(property);
}
}
cellsProperties.add(cellProperties);
}
res = cellsProperties;
} else {
res = super.getPropertyValue(name);
}
return res;
}
public static class HistoryShapePropertiesNames extends TextArrayShapePropertiesNames {
private static transient String[] props = new String[] { "HISTORY_SIZE" };
public HistoryShapePropertiesNames() {
super();
for (int i = 0; i < props.length; i++) {
propertyNames.add(0, props[i]); // insert at begining hsitory
// properties
}
}
}
}