package org.nightlabs.jfire.issuetracking.ui.issuehistory;
import java.io.ByteArrayInputStream;
import java.text.DateFormat;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import javax.jdo.FetchPlan;
import javax.jdo.JDOHelper;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.nightlabs.base.ui.layout.WeightedTableLayout;
import org.nightlabs.base.ui.table.AbstractTableComposite;
import org.nightlabs.base.ui.table.TableLabelProvider;
import org.nightlabs.jdo.NLJDOHelper;
import org.nightlabs.jfire.base.jdo.notification.JDOLifecycleEvent;
import org.nightlabs.jfire.base.jdo.notification.JDOLifecycleListener;
import org.nightlabs.jfire.base.jdo.notification.JDOLifecycleManager;
import org.nightlabs.jfire.base.ui.jdo.notification.JDOLifecycleAdapterJob;
import org.nightlabs.jfire.issue.Issue;
import org.nightlabs.jfire.issue.history.FetchGroupsIssueHistoryItem;
import org.nightlabs.jfire.issue.history.IssueHistoryItem;
import org.nightlabs.jfire.issue.history.IssueHistoryItemDAO;
import org.nightlabs.jfire.issue.id.IssueID;
import org.nightlabs.jfire.issuetracking.ui.resource.Messages;
import org.nightlabs.jfire.jdo.notification.DirtyObjectID;
import org.nightlabs.jfire.jdo.notification.IJDOLifecycleListenerFilter;
import org.nightlabs.jfire.jdo.notification.JDOLifecycleState;
import org.nightlabs.jfire.jdo.notification.SimpleLifecycleListenerFilter;
import org.nightlabs.progress.NullProgressMonitor;
/**
* This composite lists all {@link IssueHistoryItem}s of an issue in a table.
*
* @author Chairat Kongarayawetchakun - chairat[at]nightlabs[dot]de
* @author Khaireel Mohamed - khaireel at nightlabs dot de
*/
public class IssueHistoryTable extends AbstractTableComposite<IssueHistoryItem> {
/**
* Creates a new instance of an IssueHistoryTable.
*/
public IssueHistoryTable(Composite parent, int style) {
super(parent, style);
getTableViewer().addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent e) {
}
});
JDOLifecycleManager.sharedInstance().addLifecycleListener(myLifecycleListener);
addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent event) {
JDOLifecycleManager.sharedInstance().removeLifecycleListener(myLifecycleListener);
}
});
getTableViewer().setComparator(new ViewerComparator() {
@Override
public void sort(Viewer viewer, Object[] elements) {
Arrays.sort(elements, new Comparator<Object>() {
public int compare(Object object1, Object object2) {
return -((IssueHistoryItem)object1).getCreateTimestamp().compareTo(((IssueHistoryItem)object2).getCreateTimestamp());
}
});
}
});
// Since 29 May 2009.
addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(DisposeEvent event) { disposeAllImages(); }
});
}
private JDOLifecycleListener myLifecycleListener = new JDOLifecycleAdapterJob(Messages.getString("org.nightlabs.jfire.issuetracking.ui.issuehistory.IssueHistoryTable.lifeCycleListener.loading.text")) { //$NON-NLS-1$
private IJDOLifecycleListenerFilter filter = new SimpleLifecycleListenerFilter(
Issue.class,
true,
JDOLifecycleState.NEW);
public IJDOLifecycleListenerFilter getJDOLifecycleListenerFilter() {
return filter;
}
public void notify(final JDOLifecycleEvent event) {
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
Collection<DirtyObjectID> dirtyObjectIDs = event.getDirtyObjectIDs();
for (DirtyObjectID dirtyObjectID : dirtyObjectIDs) {
IssueID issueID = (IssueID)dirtyObjectID.getObjectID();
Collection<IssueHistoryItem> histories = IssueHistoryItemDAO.sharedInstance().getIssueHistoryItems(
issueID,
new String[] {FetchPlan.DEFAULT, FetchGroupsIssueHistoryItem.FETCH_GROUP_LIST},
NLJDOHelper.MAX_FETCH_DEPTH_NO_LIMIT,
new NullProgressMonitor());
setInput(histories);
}
}
});
}
};
/* (non-Javadoc)
* @see org.nightlabs.base.ui.table.AbstractTableComposite#createTableColumns(org.eclipse.jface.viewers.TableViewer, org.eclipse.swt.widgets.Table)
*/
@Override
protected void createTableColumns(TableViewer tableViewer, Table table) {
TableColumn tc;
tc = new TableColumn(table, SWT.LEFT);
tc.setMoveable(true);
tc.setText(Messages.getString("org.nightlabs.jfire.issuetracking.ui.issuehistory.IssueHistoryTable.tableColumn.date.text")); //$NON-NLS-1$
tc = new TableColumn(table, SWT.LEFT);
tc.setMoveable(true);
tc.setText(Messages.getString("org.nightlabs.jfire.issuetracking.ui.issuehistory.IssueHistoryTable.tableColumn.userName.text")); //$NON-NLS-1$
tc = new TableColumn(table, SWT.LEFT);
tc.setMoveable(true);
tc.setText(Messages.getString("org.nightlabs.jfire.issuetracking.ui.issuehistory.IssueHistoryTable.tableColumn.action.text")); //$NON-NLS-1$
WeightedTableLayout layout = new WeightedTableLayout(new int[]{15, 10, 75});
table.setLayout(layout);
}
/* (non-Javadoc)
* @see org.nightlabs.base.ui.table.AbstractTableComposite#setTableProvider(org.eclipse.jface.viewers.TableViewer)
*/
@Override
protected void setTableProvider(TableViewer tableViewer) {
tableViewer.setContentProvider(new ArrayContentProvider()); //(new TableContentProvider());
tableViewer.setLabelProvider(new IssueHistoryListLabelProvider());
}
private static DateFormat dateTimeFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
// ------------------------------------------------------------------------------------------------------
// Cleanly control the images, so that we dont have to keep creating new ones, even after it was
// removed from the table entry, and the re-added again later.
private Map<String, Image> imageKey2Image = new HashMap<String, Image>();
/**
* Disposes all images.
*/
private void disposeAllImages() {
for (Image image : imageKey2Image.values())
image.dispose();
imageKey2Image.clear();
}
// -------------------------------------------------------------------------------------------------------------------------|
class IssueHistoryListLabelProvider extends TableLabelProvider {
@Override
public String getColumnText(Object element, int columnIndex) {
if (element instanceof IssueHistoryItem) {
IssueHistoryItem issueHistoryItem = (IssueHistoryItem) element;
switch (columnIndex) {
case(0): return dateTimeFormat.format(issueHistoryItem.getCreateTimestamp());
case(1): return issueHistoryItem.getUser().getName();
case(2): return issueHistoryItem.getDescription(); //.getChange();
}
}
return ""; //$NON-NLS-1$
}
@Override
public Image getColumnImage(Object element, int columnIndex) {
if (element != null && element instanceof IssueHistoryItem && columnIndex == 2) {
IssueHistoryItem issueHistoryItem = (IssueHistoryItem)element;
String imageKey = JDOHelper.getObjectId(issueHistoryItem).toString();
Image icon = imageKey2Image.get(imageKey);
if (icon == null) {
byte[] iconByte = issueHistoryItem.getIcon16x16Data();
if (iconByte != null) {
ByteArrayInputStream in = new ByteArrayInputStream( iconByte );
icon = new Image(getDisplay(), in);
imageKey2Image.put(imageKey, icon);
}
}
return icon;
}
return super.getColumnImage(element, columnIndex);
}
}
// -------------------------------------------------------------------------------------------------------------------------|
public void setLoadingStatus() {
super.setInput(Messages.getString("org.nightlabs.jfire.issuetracking.ui.issuehistory.IssueHistoryTable.tableColumnText.loading.text")); //$NON-NLS-1$
}
// TO CHECK: Do we really need these? Kai
// --> CHECKED: No we dont. Kai.
// private IssueID issueID;
// public void setIssueHistoryItems(IssueID issueID, Collection<IssueHistoryItem> issueHistoryItems) {
// if (issueID == null)
// throw new IllegalArgumentException("issueID == null"); //$NON-NLS-1$
//
// this.issueID = issueID;
// super.setInput(issueHistoryItems);
// }
//
// @Override
// public void setInput(Object input) {
// throw new UnsupportedOperationException("Use setIssueHistories(...) or setLoadingStatus(...) instead!"); //$NON-NLS-1$
// }
}