/**
* This file is part of HIDB2.
*
* HIDB2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PoJamas 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 Public License for more details.
*
* You should have received a copy of the GNU Lesser Public License
* along with PoJamas. If not, see <http://www.gnu.org/licenses/>.
*/
package hidb2.gui.editor;
import hidb2.gui.util.AbstractInvertableSorter;
import hidb2.gui.util.Parts;
import hidb2.gui.util.TableSortSelectionListener;
import hidb2.kern.AttrEnumItemChecker;
import hidb2.kern.AttrImage;
import hidb2.kern.AttrImageChecker;
import hidb2.kern.AttrType;
import hidb2.kern.Attribut;
import hidb2.kern.AttributedDescription;
import hidb2.kern.HIDBConst;
import hidb2.kern.StatusCycle;
import hidb2.kern.ValuedInstance;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Logger;
import org.eclipse.jface.util.Util;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnViewerEditor;
import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;
import org.eclipse.jface.viewers.FocusCellOwnerDrawHighlighter;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerEditor;
import org.eclipse.jface.viewers.TableViewerFocusCellManager;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
/**
* TableViewer dedicated to Valued Instance edition.
*/
public class ValuedInstanceTableViewer extends TableViewer implements HIDBConst
{
final static Logger log = Logger.getLogger("hidb2.gui.editor");
protected AttributedDescription _fd;
/** Index mapping between table indice and valuedinstance attribut index */
private int[] _mapIdx;
/** Mapped Attribut table that matches table indice */
private Attribut[] _mapAttr;
private String[] _columnProp;
private CellEditor[] _cellEdt;
private List<ModifyListener> _lstModLstn = new ArrayList<ModifyListener>();
/** Size of the biggest icon */
private int _maxIconSize = -1;
/**
* Create a tableviewer for the given Attributed description.
*
* @param parent
* @param style
* @param fd
*/
public ValuedInstanceTableViewer(Composite parent, int style, AttributedDescription fd)
{
super(parent, style);
_fd = fd;
// Check first that definition data are complete
int nbcol = _fd.getAttributList().size();
_columnProp = new String[nbcol];
_mapIdx = new int[nbcol];
_mapAttr = new Attribut[nbcol];
for (int i = 0; i < nbcol; i++)
{
Attribut attr = _fd.getAttributList().get(i);
_mapAttr[attr.getDisplayOrder()] = attr;
_columnProp[attr.getDisplayOrder()] = attr.getColName();
_mapIdx[attr.getDisplayOrder()] = i;
}
// Transversal TAB key Management - Tested OK
TableViewerFocusCellManager tvfcm = new TableViewerFocusCellManager(this, new FocusCellOwnerDrawHighlighter(this));
ColumnViewerEditorActivationStrategy cveas = new ColumnViewerEditorActivationStrategy(this);
TableViewerEditor.create(this, tvfcm, cveas, ColumnViewerEditor.TABBING_HORIZONTAL
| ColumnViewerEditor.TABBING_CYCLE_IN_ROW);
}
public int getPreferredWidth()
{
int w = 0;
for (int indice = 0; indice < _fd.getAttributList().size(); indice++)
{
w += _mapAttr[indice].getColumnWidth();
}
return w;
}
/**
* This method customizes the titles and the contents of the columns.
* It installs the editors.
* It shall be called after the definition of all attributes.
*
*/
public void createMMI()
{
Table tabFile = getTable();
tabFile.setHeaderVisible(true);
tabFile.setLinesVisible(true);
setContentProvider(new GenericTabContentProvider());
setLabelProvider(new GenericTabLabelProvider());
// Create Columns
TableColumn colonne;
TableSortSelectionListener listener;
for (int indice = 0; indice < _fd.getAttributList().size(); indice++)
{
int wicon = 0;
Attribut attr = _mapAttr[indice];
colonne = new TableColumn(tabFile, SWT.LEFT);
colonne.setText(attr.getName());
if (attr.getType() == AttrType.T_Image)
{
wicon = ((AttrImageChecker) attr.getChecker()).getIconSize();
if (wicon > _maxIconSize)
{
_maxIconSize = wicon;
}
}
colonne.setWidth(Math.max(attr.getColumnWidth(), wicon));
// Create sorter
listener = new TableSortSelectionListener(this, colonne, new GenericTabSorter(indice), SWT.UP, false);
// Initialise sort for 1st column
if (indice == 0)
{
listener.chooseColumnForSorting();
}
}
// Set the editors, cell modifier, and column properties
setColumnProperties(_columnProp);
setCellModifier(new GenericCellModifier());
setCellEditors(createCellEditor());
}
public CellEditor[] createCellEditor()
{
_cellEdt = new CellEditor[_columnProp.length + 1];
for (int i = 0; i < _fd.getAttributList().size(); i++)
{
_cellEdt[i] = Parts.createCellEditor(_mapAttr[i], getTable());
}
return _cellEdt;
}
/**
* Set the layout data on the undelying SWT table.
* @param ld
*/
public void setLayoutData(Object ld)
{
getTable().setLayoutData(ld);
}
/**
* Adds the listener to the collection of listeners who will
* be notified when the receiver's text is modified, by sending
* it one of the messages defined in the <code>ModifyListener</code>
* interface.
*
* @param listener the listener which should be notified
*
*/
public void addModifyListener(ModifyListener listener)
{
if (listener != null)
{
_lstModLstn.add(listener);
}
}
class GenericTabLabelProvider implements ITableLabelProvider
{
public Image getColumnImage(Object element, int columnIndex)
{
Image img = null;
// The Element is a ValuedInstance
if (_mapAttr[columnIndex].getType() == AttrType.T_Image)
{
ValuedInstance vi = (ValuedInstance) element;
AttrImage ai = (AttrImage) vi.getValue(_mapIdx[columnIndex]);
if (ai != null)
{
img = ai.getSqrImage(getTable().getDisplay(), _maxIconSize);
}
}
return img;
}
public String getColumnText(Object element, int columnIndex)
{
// The Element is a ValuedInstance
ValuedInstance vi = (ValuedInstance) element;
Object val = vi.getValue(_mapIdx[columnIndex]);
String s = _mapAttr[columnIndex].format(val);
return s;
}
public void addListener(ILabelProviderListener listener)
{
}
public void dispose()
{
}
public boolean isLabelProperty(Object element, String property)
{
return true;
}
public void removeListener(ILabelProviderListener listener)
{
}
}
// Input = List<DataFile>
class GenericTabContentProvider implements IStructuredContentProvider
{
public GenericTabContentProvider()
{
}
@SuppressWarnings("unchecked")
public Object[] getElements(Object inputElement)
{
// Filter DELETED lines
List<ValuedInstance> lvi = (List<ValuedInstance>) inputElement;
List<ValuedInstance> lvif = new ArrayList<ValuedInstance>(lvi.size());
for (ValuedInstance vi : lvi)
{
if (vi.getStatus() != StatusCycle.DELETED)
{
lvif.add(vi);
}
}
return lvif.toArray();
}
public void dispose()
{
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
{
}
}
/**
* Sorter for any Poser data represented in a Table.
*
*/
class GenericTabSorter extends AbstractInvertableSorter
{
/** Concerned Column */
private int _colIdx;
/**
* Constructor
* @param attrDescr Attribut Descriptor
*/
public GenericTabSorter(int colIndex)
{
_colIdx = colIndex;
}
public int compare(Viewer viewer, Object e1, Object e2)
{
ValuedInstance vi1 = (ValuedInstance) e1;
ValuedInstance vi2 = (ValuedInstance) e2;
return Util.compare((Comparable<?>) vi1.getValue(_mapIdx[_colIdx]), (Comparable<?>) vi2
.getValue(_mapIdx[_colIdx]));
}
}
final protected int getPropIndex(String s)
{
int res = 0;
while (res < _columnProp.length)
{
if (s.equals(_columnProp[res]))
{
return res;
}
else
{
res++;
}
}
return res;
}
public boolean isModifiable(Object element, String property)
{
return true;
}
class GenericCellModifier implements ICellModifier
{
@Override
public boolean canModify(Object element, String property)
{
return isModifiable(element, property);
}
@Override
public Object getValue(Object element, String property)
{
int idx = getPropIndex(property);
ValuedInstance vi = (ValuedInstance) element;
Object o = vi.getValue(_mapIdx[idx]);
Attribut attr = _fd.getAttributList().get(_mapIdx[idx]);
if ((attr.getType() == AttrType.T_RefList) && (o != null))
{
AttrEnumItemChecker aei = (AttrEnumItemChecker) attr.getChecker();
int idxName = aei.getLstEnumItem().indexOf(o);
o = new Integer(idxName);
}
return o;
}
@Override
public void modify(Object element, String property, Object value)
{
if (value != null)
{
int idx = getPropIndex(property);
ValuedInstance vi = (ValuedInstance) ((TableItem) element).getData();
Attribut attr = _fd.getAttributList().get(_mapIdx[idx]);
switch (attr.getType())
{
case T_Date:
value = new java.sql.Date(((Date) value).getTime());
break;
case T_Time:
value = new Time(((Date) value).getTime());
break;
case T_TimeStamp:
value = new Timestamp(((Date) value).getTime());
break;
case T_RefList:
int index = (Integer) value;
AttrEnumItemChecker aei = (AttrEnumItemChecker) attr.getChecker();
value = aei.getLstEnumItem().get(index);
break;
}
vi.setValue(_mapIdx[idx], value);
update(vi, new String[]
{
property
});
// Fire ModifyEvent
Event ev = new Event();
ev.data = vi;
ev.widget = getTable();
ModifyEvent me = new ModifyEvent(ev);
for (ModifyListener ml : _lstModLstn)
{
ml.modifyText(me);
}
}
}
}
}