package org.nightlabs.jfire.asterisk.ui.asteriskserver;
import java.util.Collection;
import java.util.Map;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.nightlabs.base.ui.labelprovider.ColumnSpanLabelProvider;
import org.nightlabs.base.ui.layout.WeightedTableLayout;
import org.nightlabs.base.ui.table.AbstractTableComposite;
import org.nightlabs.jfire.asterisk.AsteriskServer;
import org.nightlabs.jfire.asterisk.ui.resource.Messages;
/**
* @author Chairat Kongarayawetchakun <!-- chairat [AT] nightlabs [DOT] de -->
*/
public class CallFilePropertyTable
extends AbstractTableComposite<Map.Entry<String, String>>
{
public static final String KEY_COLUMN_ID = "key"; //$NON-NLS-1$
public static final String VALUE_COLUMN_ID = "value"; //$NON-NLS-1$
/**
* @param parent
* @param style
*/
public CallFilePropertyTable(Composite parent) {
this(parent, SWT.NONE, DEFAULT_STYLE_MULTI_BORDER);
}
/**
* @param parent
* @param style
* @param initTable
*/
public CallFilePropertyTable(Composite parent, int style, int viewerStyle) {
super(parent, style, true, viewerStyle);
getTable().setHeaderVisible(true);
getTableViewer().setSorter(new ViewerSorter());
// hookContextMenu();
createContextMenu(getTableViewer().getControl());
}
// ------------------------------------------------------------------------------------- ++ ------------------------------->>
// Note: @Kai
// Since 2010.04.13, we now have the super class ContextMenuReadyXComposite (which the AbstractTableComposite now extends)
// to efficiently manage (priority-ordered) context-menus when needed (thru the method integratePriorityOrderedContextMenu()),
// which has been streamlined to handle 3 types of contextMenuContributions:
// (i) IContributionItem, (ii) IAction, and (iii) IViewActionDelegate.
// ------------------------------------------------------------------------------------- ++ ------------------------------->>
// private void hookContextMenu() {
// MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
// menuMgr.setRemoveAllWhenShown(true);
// menuMgr.addMenuListener(new IMenuListener() {
// public void menuAboutToShow(IMenuManager manager) {
// CallFilePropertyTable.this.fillContextMenu(manager);
// }
// });
// Menu menu = menuMgr.createContextMenu(getTableViewer().getControl());
// getTableViewer().getControl().setMenu(menu);
//// if (getSite() != null)
//// getSite().registerContextMenu(menuMgr, getTableViewer());
// }
//
// /**
// * Contains instances of both, {@link IContributionItem} and {@link IAction}
// */
// private List<Object> contextMenuContributions;
//
// public void addContextMenuContribution(IContributionItem contributionItem)
// {
// if (contextMenuContributions == null)
// contextMenuContributions = new LinkedList<Object>();
//
// contextMenuContributions.add(contributionItem);
// }
//
// public void addContextMenuContribution(IAction action)
// {
// if (contextMenuContributions == null)
// contextMenuContributions = new LinkedList<Object>();
//
// contextMenuContributions.add(action);
// }
//
// private void fillContextMenu(IMenuManager manager) {
// if (contextMenuContributions != null) {
// for (Object contextMenuContribution : contextMenuContributions) {
// if (contextMenuContribution instanceof IContributionItem)
// manager.add((IContributionItem)contextMenuContribution);
// else if (contextMenuContribution instanceof IAction)
// manager.add((IAction)contextMenuContribution);
// else
// throw new IllegalStateException("How the hell got an instance of " + (contextMenuContribution == null ? "null" : contextMenuContribution.getClass()) + " in the contextMenuContributions list?!"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
// }
// }
//
// // Other plug-ins can contribute their actions here
// manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
// }
// ------------------------------------------------------------------------------------- ++ ------------------------------->>
@Override
protected void createTableColumns(TableViewer tableViewer, Table table) {
TableColumn tc;
tc = new TableColumn(table, SWT.LEFT); // @column 0
tc.setMoveable(true);
tc.setText(Messages.getString("org.nightlabs.jfire.asterisk.ui.asteriskserver.CallFilePropertyTable.columnHeader[key].text")); //$NON-NLS-1$
tc = new TableColumn(table, SWT.LEFT); // @column 1
tc.setMoveable(true);
tc.setText(Messages.getString("org.nightlabs.jfire.asterisk.ui.asteriskserver.CallFilePropertyTable.columnHeader[value].text")); //$NON-NLS-1$
WeightedTableLayout layout = new WeightedTableLayout(new int[]{
30,
70});
table.setLayout(layout);
tableViewer.setColumnProperties(new String[] {KEY_COLUMN_ID, VALUE_COLUMN_ID});
tableViewer.setCellEditors(new CellEditor[] {
null,
new TextCellEditor(table)}
);
tableViewer.setCellModifier(new CallFilePropertyCellModifier());
}
@Override
protected void setTableProvider(TableViewer tableViewer) {
tableViewer.setContentProvider(new CallFilePropertyContentProvider());
tableViewer.setLabelProvider(new CallFilePropertyLabelProvider(tableViewer));
}
@Override
public void setInput(Object input) {
if (!(input instanceof AsteriskServer))
throw new IllegalArgumentException("input must be an instance of AsteriskServer, but is: " + input); //$NON-NLS-1$
setAsteriskServer((AsteriskServer)input);
}
private AsteriskServer asteriskServer;
private void setAsteriskServer(AsteriskServer asteriskServer) {
this.asteriskServer = asteriskServer;
super.setInput(asteriskServer);
}
protected class CallFilePropertyContentProvider implements IStructuredContentProvider {
@Override
public Object[] getElements(Object inputElement) {
if (inputElement instanceof AsteriskServer) {
AsteriskServer asteriskServer = (AsteriskServer) inputElement;
Collection<Map.Entry<String, String>> c = asteriskServer.getCallFileProperties().entrySet();
@SuppressWarnings("unchecked")
Map.Entry<String, String>[] a = c.toArray(new Map.Entry[c.size()]);
return a;
}
return null;
}
@Override
public void dispose() {
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
}
private class CallFilePropertyLabelProvider
extends ColumnSpanLabelProvider
{
public CallFilePropertyLabelProvider(ColumnViewer columnViewer) {
super(columnViewer);
}
@Override
public String getColumnText(Object element, int columnIndex)
{
@SuppressWarnings("unchecked")
Map.Entry<String, String> entry = (Map.Entry<String, String>)element;
switch (columnIndex) {
case 0:
return entry.getKey();
case 1:
return entry.getValue();
default: return "";//$NON-NLS-1$
}
}
@Override
protected int[][] getColumnSpan(Object element) {
return null;
}
}
private class CallFilePropertyCellModifier implements ICellModifier {
@Override
public boolean canModify(Object element, String property) {
return property.equals(VALUE_COLUMN_ID);
}
@Override
public Object getValue(Object element, String property) {
if(property.equals(VALUE_COLUMN_ID)){
@SuppressWarnings("unchecked")
Map.Entry<String, String> me = (Map.Entry<String, String>)element;
return me.getValue();
}
return null;
}
@Override
public void modify(Object element, String property, Object value) {
if (!property.equals(VALUE_COLUMN_ID)){
return;
}
TableItem tableItem = (TableItem)element;
@SuppressWarnings("unchecked")
Map.Entry<String, String> entry = (Map.Entry<String, String>)tableItem.getData();
if (value.equals(entry.getValue()))
return; // modify only if really changed (e.g. no mark-dirty, if the value is unchanged)
// entry.setValue((String)value);
//Don't know what's wrong with it, These lines fix the NPE of the element. (I think because of the Map.Entry.equals' method)
asteriskServer.setCallFileProperty(entry.getKey(), (String)value);
// setAsteriskServer(asteriskServer); // This line calls setInput and thus all selection and other properties get lost.
// getTableViewer().update(entry, new String[] { property });
getTableViewer().refresh();
fireModification();
}
}
private ListenerList modifyListeners = new ListenerList();
public void addCallFilePropertyModifyListener(CallFilePropertyModifyListener listener) {
modifyListeners.add(listener);
}
public void removeCallFilePropertyModifyListener(CallFilePropertyModifyListener listener) {
modifyListeners.remove(listener);
}
private void fireModification()
{
CallFilePropertyModifyEvent event = new CallFilePropertyModifyEvent(this);
for( int i=0; i< modifyListeners.size(); i++){
CallFilePropertyModifyListener modifylistener = (CallFilePropertyModifyListener)modifyListeners.getListeners()[i];
modifylistener.modifyValue(event);
}
}
}