/*
* JBoss, Home of Professional Open Source.
*
* See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing.
*
* See the AUTHORS.txt file distributed with this work for a full listing of individual contributors.
*/
package org.teiid.designer.xsd.ui.editor;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.TableWrapData;
import org.teiid.core.designer.ModelerCoreException;
import org.teiid.designer.core.ModelerCore;
import org.teiid.designer.core.TransactionRunnable;
import org.teiid.designer.core.transaction.UnitOfWork;
import org.teiid.designer.ui.actions.ClipboardActionHandler;
import org.teiid.designer.ui.actions.ClipboardActionsAdapter;
import org.teiid.designer.ui.common.eventsupport.SelectionUtilities;
import org.teiid.designer.ui.common.util.SystemClipboardUtilities;
import org.teiid.designer.ui.common.widget.AbstractTableLabelProvider;
import org.teiid.designer.ui.common.widget.DefaultContentProvider;
import org.teiid.designer.ui.forms.ComponentSetEvent;
import org.teiid.designer.ui.forms.ComponentSetMonitor;
import org.teiid.designer.ui.forms.DialogProvider;
import org.teiid.designer.xsd.ui.ModelerXsdUiConstants;
/**
* @since 8.0
*/
public class TableFacetSet extends AbstractFacetSet implements MultiFacetSet {
private static final String COL_SEP = "\t"; //$NON-NLS-1$
static final String LINE_SEP = System.getProperty("line.separator"); //$NON-NLS-1$
static final String TRANSACTION_PASTE = GUIFacetHelper.getString("TableFacetSet.transactionPaste"); //$NON-NLS-1$
private static final String TRANSACTION_DELETE = GUIFacetHelper.getString("TableFacetSet.transactionDelete"); //$NON-NLS-1$
private final DialogProvider provider;
Object transactionSource;
TableViewer viewer;
private List dataList;
private MyListener myList;
private ComponentSetMonitor mon;
public TableFacetSet( String id,
String labelName,
DialogProvider dlp ) {
super(id, labelName, false, false);
provider = dlp;
}
public void setTransactionSource( Object transactionSource ) {
this.transactionSource = transactionSource;
}
@Override
protected void addMainControl( Composite parent,
FormToolkit ftk,
ComponentSetMonitor mon ) {
this.mon = mon;
// init:
init();
// set up viewer:
viewer = new TableViewer(ftk.createTable(parent, SWT.MULTI | SWT.BORDER | SWT.FLAT | SWT.FULL_SELECTION));
viewer.setContentProvider(new MyContentProvider());
viewer.setLabelProvider(new MyTableLabelProvider());
viewer.setSorter(new ViewerSorter());
// set up table:
Table table = viewer.getTable();
table.setLayoutData(new TableWrapData(TableWrapData.FILL_GRAB, TableWrapData.FILL_GRAB));
table.setHeaderVisible(true);
table.setLinesVisible(true);
// defect 18041 -- support copy/paste
new ClipboardActionsAdapter(table, new MyClipActionHandler());
// set up columns:
TableColumn col = new TableColumn(table, SWT.LEFT);
col.setText(LABEL_VALUE);
col = new TableColumn(table, SWT.LEFT);
col.setText(LABEL_DESCRIPTION);
// pack the columns to get them to show up:
packColumns();
// hook it all together and add listener:
viewer.setInput(dataList);
viewer.addDoubleClickListener(myList);
// button panel:
Composite c = ftk.createComposite(parent);
c.setLayout(new FillLayout(SWT.VERTICAL));
// add:
final Button add = ftk.createButton(c, LABEL_ADD, SWT.NONE);
add.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected( SelectionEvent e ) {
addRowObject();
}
});
// edit:
final Button edit = ftk.createButton(c, provider.getLaunchButtonText(), SWT.NONE);
viewer.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged( SelectionChangedEvent event ) {
edit.setEnabled(SelectionUtilities.isSingleSelection(event.getSelection()));// !event.getSelection().isEmpty());
}
});
edit.setEnabled(false);
edit.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected( SelectionEvent e ) {
editRowObject(SelectionUtilities.getSelectedObject(viewer.getSelection()));
}
});
// remove:
final Button remove = ftk.createButton(c, LABEL_REMOVE, SWT.NONE);
remove.setEnabled(false);
viewer.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged( SelectionChangedEvent event ) {
remove.setEnabled(!event.getSelection().isEmpty());
}
});
remove.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected( SelectionEvent e ) {
removeSelectedRows();
}
});
}
@Override
protected void setMainValue( Object value ) {
if (value instanceof List) {
init();
// copy this list to our own:
List l = (List)value;
dataList.clear();
dataList.addAll(l);
// update gui, if present:
if (viewer != null) {
viewer.refresh();
reflow();
} // endif
} else if (value == null) {
clear();
} // endif
}
@Override
public void addValue( FacetValue fv,
boolean reflow ) {
init();
dataList.add(fv);
if (viewer != null) {
viewer.add(fv);
if (reflow) reflow();
} // endif
}
@Override
public void reflow() {
packColumns();
getCategory().reflowForm();
}
@Override
public void clear() {
init();
dataList.clear();
if (viewer != null) {
viewer.refresh();
reflow();
} // endif
}
//
// Overrides:
//
//
// Utility methods:
//
private void init() {
if (dataList == null) {
dataList = new ArrayList();
myList = new MyListener();
} // endif
}
private void packColumns() {
Table table = viewer.getTable();
for (int i = 0; i < table.getColumnCount(); i++) {
TableColumn col = table.getColumn(i);
col.pack();
if (col.getWidth() > 200) {
col.setWidth(200);
} // endif
} // endfor
}
void addRowObject() {
provider.showDialog(viewer.getTable().getShell(), new FacetValue());
if (!provider.wasCancelled()) {
FacetValue newVal = (FacetValue)provider.getValue();
addValue(newVal, true);
fireChange(newVal, false);
} // endif
}
void editRowObject( Object selected ) {
provider.showDialog(viewer.getTable().getShell(), selected);
if (!provider.wasCancelled()) {
viewer.refresh(provider.getValue());
packColumns();
fireChange((FacetValue)selected, false);
} // endif
}
private void removeRowObjects( final List selected ) {
dataList.removeAll(selected);
viewer.remove(selected.toArray());
reflow();
final TransactionRunnable runnable = new TransactionRunnable() {
@Override
public Object run( final UnitOfWork uow ) {
Iterator itor = selected.iterator();
while (itor.hasNext()) {
FacetValue fv = (FacetValue)itor.next();
fv.value = null;
fireChange(fv, true);
} // endwhile
return null;
}
}; // endanon transaction
try {
ModelerCore.getModelEditor().executeAsTransaction(runnable, TRANSACTION_DELETE, true, true, transactionSource);
} catch (ModelerCoreException mce) {
ModelerXsdUiConstants.Util.log(mce);
} // endtry
}
void fireChange( FacetValue newValue,
boolean delete ) {
mon.update(new ComponentSetEvent(this, delete, newValue));
}
void removeSelectedRows() {
removeRowObjects(SelectionUtilities.getSelectedObjects(viewer.getSelection()));
}
class MyListener implements IDoubleClickListener {
@Override
public void doubleClick( DoubleClickEvent event ) {
editRowObject(((IStructuredSelection)event.getSelection()).getFirstElement());
}
}
static class MyContentProvider extends DefaultContentProvider {
private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
@Override
public Object[] getElements( Object inputElement ) {
if (inputElement instanceof List) {
List l = (List)inputElement;
if (l.size() > 0) {
return l.toArray();
} // endif
} // endif
return EMPTY_OBJECT_ARRAY;
}
}
static class MyTableLabelProvider extends AbstractTableLabelProvider implements ILabelProvider {
private static final int VALUE_COLUMN = 0;
private static final int DESC_COLUMN = 1;
@Override
public String getColumnText( Object element,
int columnIndex ) {
if (element instanceof FacetValue) {
FacetValue fv = (FacetValue)element;
switch (columnIndex) {
case VALUE_COLUMN:
// defect 18304 - we were getting a classCastEx here on occasion:
return (fv.value != null) ? fv.value.toString() : null;
case DESC_COLUMN:
return fv.description;
default:
break;
} // endswitch
} // endif
return null;
}
@Override
public Image getImage( Object element ) {
return null;
}
@Override
public String getText( Object element ) {
if (element instanceof FacetValue) {
FacetValue fv = (FacetValue)element;
return (fv.value != null) ? fv.value.toString() : fv.toString();
} // endif
return (element != null) ? element.toString() : null;
}
}
class MyClipActionHandler implements ClipboardActionHandler {
@Override
public void cut() {
copy();
delete();
}
@Override
public void copy() {
StringBuffer toClip = new StringBuffer();
// TODO much of this code should be placed in SystemClipboardUtils...
List l = ((IStructuredSelection)viewer.getSelection()).toList();
int size = l.size();
for (int i = 0; i < size; i++) {
FacetValue fv = (FacetValue)l.get(i);
if (i > 0) {
// not first time, add CRLF:
toClip.append(LINE_SEP);
} // endif
toClip.append(fv.value).append(COL_SEP);
if (fv.description != null && fv.description.length() > 0) {
toClip.append(fv.description);
} // endif
} // endfor
SystemClipboardUtilities.setContents(toClip.toString());
}
@Override
public void paste() {
final TransactionRunnable runnable = new TransactionRunnable() {
@Override
public Object run( final UnitOfWork uow ) {
String contents = SystemClipboardUtilities.getContents();
if (contents != null) {
List toInsert = SystemClipboardUtilities.convertTableData(contents);
for (int i = 0; i < toInsert.size(); i++) {
List columns = (List)toInsert.get(i);
int size = columns.size();
// check format:
if (size != 1 && size != 2) {
ModelerXsdUiConstants.Util.log(ModelerXsdUiConstants.Util.getString("TableFacetSet.badRowFormat", columns.toString())); //$NON-NLS-1$
// don't add anything for this row.
continue;
} // endif
FacetValue fv = new FacetValue();
fv.value = columns.get(0);
// set description if available:
if (size == 2) {
fv.description = (String)columns.get(1);
} // endif
addValue(fv, false);
fireChange(fv, false);
} // endfor
} // endif
return null;
}
}; // endanon transaction
try {
ModelerCore.getModelEditor().executeAsTransaction(runnable, TRANSACTION_PASTE, true, true, transactionSource);
} catch (ModelerCoreException mce) {
ModelerXsdUiConstants.Util.log(mce);
} // endtry
reflow();
}
@Override
public void delete() {
removeSelectedRows();
}
@Override
public void selectAll() {
viewer.getTable().selectAll();
}
@Override
public void addSelectionChangedListener( ISelectionChangedListener listener ) {
viewer.addSelectionChangedListener(listener);
}
} // endclass MyClipActionHandler
// //
// // Testing methods:
// //
// public static void main(String[] args) {
// Display display = new Display();
// Shell shell = new Shell(display);
// shell.setText("Simple Datatypes Editor as a Form");
// shell.setLayout(new FillLayout());
//
// TableFacetSet tfs = new TableFacetSet("testid", "labelname", new FacetHelper.NullDialogProvider("launch"));
// tfs.addFormControls(shell, new FormToolkit(Display.getDefault()), 10);
// LayoutDebugger.debugLayout(shell);
//
// shell.setBounds(100, 100, 650, 550);
// shell.open();
// while (!shell.isDisposed()) {
// if (!display.readAndDispatch())
// display.sleep();
// }
// display.dispose();
// }
}