/*
* Copyright (c) 2013 Data Harmonisation Panel
*
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution. If not, see <http://www.gnu.org/licenses/>.
*
* Contributors:
* Data Harmonisation Panel <http://www.dhpanel.eu>
*/
package eu.esdihumboldt.hale.ui.views.properties.entity;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
import com.google.common.collect.Multiset.Entry;
import eu.esdihumboldt.hale.common.align.model.impl.PropertyEntityDefinition;
import eu.esdihumboldt.hale.common.schema.SchemaSpaceID;
import eu.esdihumboldt.hale.ui.common.CommonSharedImages;
import eu.esdihumboldt.hale.ui.service.values.OccurringValues;
import eu.esdihumboldt.hale.ui.service.values.OccurringValuesListener;
import eu.esdihumboldt.hale.ui.service.values.OccurringValuesService;
/**
* Page displaying the occurring values for a property.
*
* @author Simon Templer
*/
public class OccurringValuesSection extends AbstractEntityDefSection {
private final OccurringValuesService service;
private TableViewer values;
private Button refresh;
private Button copy;
private OccurringValuesListener ovlistener;
/**
* Default constructor.
*/
public OccurringValuesSection() {
super();
service = PlatformUI.getWorkbench().getService(OccurringValuesService.class);
}
@Override
public void createControls(Composite parent, TabbedPropertySheetPage aTabbedPropertySheetPage) {
super.createControls(parent, aTabbedPropertySheetPage);
Composite page = getWidgetFactory().createComposite(parent);
GridLayoutFactory.swtDefaults().numColumns(2).applyTo(page);
// refresh button
refresh = getWidgetFactory().createButton(page, null, SWT.PUSH);
refresh.setImage(CommonSharedImages.getImageRegistry().get(CommonSharedImages.IMG_REFRESH));
refresh.setToolTipText("Update the occurring values");
refresh.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
service.updateOccurringValues((PropertyEntityDefinition) getEntity());
}
});
GridDataFactory.swtDefaults().align(SWT.END, SWT.BEGINNING).grab(false, false)
.applyTo(refresh);
// values table
values = new TableViewer(getWidgetFactory().createTable(page, SWT.MULTI | SWT.BORDER));
GridDataFactory.fillDefaults().grab(true, true).span(1, 2).applyTo(values.getControl());
values.setContentProvider(new ArrayContentProvider() {
@Override
public Object[] getElements(Object inputElement) {
if (inputElement instanceof OccurringValues) {
return ((OccurringValues) inputElement).getValues().entrySet().toArray();
}
return new Object[] {};
}
});
values.setLabelProvider(new LabelProvider() {
@Override
public String getText(Object element) {
if (element instanceof Entry) {
// XXX use styled label provider instead?
Entry<?> entry = (Entry<?>) element;
if (entry.getCount() > 1) {
return super.getText(entry.getElement()) + "\t(\u00d7" + entry.getCount()
+ ")";
}
else
return super.getText(entry.getElement());
}
return super.getText(element);
}
});
values.setInput(null);
// values context menu
MenuManager manager = new MenuManager();
manager.setRemoveAllWhenShown(true);
manager.addMenuListener(new IMenuListener() {
@Override
public void menuAboutToShow(IMenuManager manager) {
// populate context menu
// get selection
ISelection selection = values.getSelection();
if (!selection.isEmpty() && selection instanceof IStructuredSelection) {
Object[] sels = ((IStructuredSelection) selection).toArray();
List<String> values = new ArrayList<String>();
for (Object sel : sels) {
if (sel instanceof Entry<?>) {
values.add(((Entry<?>) sel).getElement().toString());
}
}
if (!values.isEmpty()) {
manager.add(new AddConditionAction(getEntity(), values, false));
manager.add(new AddParentConditionAction(getEntity(), values, false));
if (values.size() > 1) {
manager.add(new Separator());
manager.add(new AddConditionAction(getEntity(), values, true));
manager.add(new AddParentConditionAction(getEntity(), values, true));
}
}
}
}
});
manager.setRemoveAllWhenShown(true);
final Menu valuesMenu = manager.createContextMenu(values.getControl());
values.getControl().setMenu(valuesMenu);
// copy button
copy = getWidgetFactory().createButton(page, null, SWT.PUSH);
copy.setImage(
PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_TOOL_COPY));
copy.setToolTipText("Copy values to the clipboard");
copy.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
copyToClipboard();
}
});
GridDataFactory.swtDefaults().align(SWT.END, SWT.BEGINNING).grab(false, false)
.applyTo(copy);
// add listener to service
service.addListener(ovlistener = new OccurringValuesListener() {
@Override
public void occurringValuesUpdated(PropertyEntityDefinition property) {
if (property.equals(OccurringValuesSection.this.getEntity())) {
update();
}
}
@Override
public void occurringValuesInvalidated(SchemaSpaceID schemaSpace) {
if (schemaSpace.equals(OccurringValuesSection.this.getEntity().getSchemaSpace())) {
update();
}
}
});
update();
}
/**
* Copy the values table to the clipboard.
*/
private void copyToClipboard() {
if (values != null) {
Table table = values.getTable();
if (table.getSelectionCount() > 0) {
TableItem rows[] = table.getItems(); // getSelection();
StringBuilder sb = new StringBuilder();
int cc = table.getColumnCount();
if (cc == 0) {
// there is a column even if used like a list
cc = 1;
}
for (int row = 0; row < rows.length; row++) {
if (row > 0)
sb.append("\n");
TableItem item = rows[row];
for (int column = 0; column < cc; column++) {
if (column > 0)
sb.append(SWT.TAB);
sb.append(item.getText(column));
}
}
Clipboard clipBoard = new Clipboard(Display.getCurrent());
clipBoard.setContents(new Object[] { sb.toString() },
new Transfer[] { TextTransfer.getInstance() });
clipBoard.dispose();
}
}
}
/**
* Update the section state.
*/
private void update() {
final Display display = PlatformUI.getWorkbench().getDisplay();
display.syncExec(new Runnable() {
@Override
public void run() {
if (values != null) {
OccurringValues ov = null;
if (getEntity() != null) {
ov = service.getOccurringValues((PropertyEntityDefinition) getEntity());
}
values.setInput(ov);
values.getControl().setEnabled(ov != null);
refresh.setEnabled(ov == null || !ov.isUpToDate());
copy.setEnabled(ov != null);
// TODO some icon to state that information is not
// up-to-date?
// relayout so scrolling is done inside table
// XXX not really working
values.getControl().getParent().layout();
values.getControl().getParent().getParent().layout();
}
}
});
}
@Override
public void refresh() {
update();
}
@Override
public boolean shouldUseExtraSpace() {
return true;
}
@Override
public void dispose() {
if (ovlistener != null) {
service.removeListener(ovlistener);
}
super.dispose();
}
}