package name.abuchen.portfolio.ui.wizards.security;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableColorProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import name.abuchen.portfolio.model.Client;
import name.abuchen.portfolio.model.Security;
import name.abuchen.portfolio.money.Values;
import name.abuchen.portfolio.online.Factory;
import name.abuchen.portfolio.online.SecuritySearchProvider;
import name.abuchen.portfolio.online.SecuritySearchProvider.ResultItem;
import name.abuchen.portfolio.ui.Messages;
import name.abuchen.portfolio.ui.PortfolioPlugin;
public class SearchSecurityWizardPage extends WizardPage
{
private Client client;
private ResultItem item;
public SearchSecurityWizardPage(Client client)
{
super("searchpage"); //$NON-NLS-1$
setTitle(Messages.SecurityMenuAddNewSecurity);
setDescription(Messages.SecurityMenuAddNewSecurityDescription);
this.client = client;
}
@Override
public void createControl(Composite parent)
{
Composite container = new Composite(parent, SWT.NULL);
GridLayoutFactory.fillDefaults().numColumns(1).applyTo(container);
final Text searchBox = new Text(container, SWT.BORDER | SWT.SINGLE);
searchBox.setText(""); //$NON-NLS-1$
searchBox.setFocus();
GridDataFactory.fillDefaults().grab(true, false).applyTo(searchBox);
final TableViewer resultTable = new TableViewer(container, SWT.FULL_SELECTION);
GridDataFactory.fillDefaults().grab(true, true).applyTo(resultTable.getControl());
TableColumn column = new TableColumn(resultTable.getTable(), SWT.NONE);
column.setText(Messages.ColumnSymbol);
column.setWidth(60);
column = new TableColumn(resultTable.getTable(), SWT.NONE);
column.setText(Messages.ColumnName);
column.setWidth(140);
column = new TableColumn(resultTable.getTable(), SWT.NONE);
column.setText(Messages.ColumnISIN);
column.setWidth(100);
column = new TableColumn(resultTable.getTable(), SWT.RIGHT);
column.setText(Messages.ColumnLastTrade);
column.setWidth(60);
column = new TableColumn(resultTable.getTable(), SWT.NONE);
column.setText(Messages.ColumnSecurityType);
column.setWidth(60);
column = new TableColumn(resultTable.getTable(), SWT.NONE);
column.setText(Messages.ColumnSecurityExchange);
column.setWidth(60);
resultTable.getTable().setHeaderVisible(true);
resultTable.getTable().setLinesVisible(true);
final Set<String> existingSymbols = new HashSet<String>();
for (Security s : client.getSecurities())
existingSymbols.add(s.getTickerSymbol());
resultTable.setLabelProvider(new ResultItemLabelProvider(existingSymbols));
resultTable.setContentProvider(ArrayContentProvider.getInstance());
searchBox.addTraverseListener(new TraverseListener()
{
@Override
public void keyTraversed(TraverseEvent e)
{
// don't forward to the default button
e.doit = false;
}
});
searchBox.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetDefaultSelected(SelectionEvent event)
{
doSearch(searchBox.getText(), resultTable);
}
});
resultTable.addSelectionChangedListener(new ISelectionChangedListener()
{
@Override
public void selectionChanged(SelectionChangedEvent event)
{
item = (ResultItem) ((IStructuredSelection) event.getSelection()).getFirstElement();
setPageComplete(item != null && item.getSymbol() != null
&& !existingSymbols.contains(item.getSymbol()));
}
});
setControl(container);
}
public ResultItem getResult()
{
return item;
}
private void doSearch(String query, TableViewer resultTable)
{
try
{
getContainer().run(true, false, m -> {
try
{
SecuritySearchProvider provider = Factory.getSearchProvider().get(0);
List<ResultItem> result = provider.search(query);
Display.getDefault().asyncExec(() -> resultTable.setInput(result));
}
catch (IOException e)
{
PortfolioPlugin.log(e);
Display.getDefault().asyncExec(() -> setErrorMessage(e.getMessage()));
}
});
}
catch (InvocationTargetException | InterruptedException e)
{
PortfolioPlugin.log(e);
}
}
private static class ResultItemLabelProvider extends LabelProvider
implements ITableLabelProvider, ITableColorProvider
{
private final Set<String> symbols;
public ResultItemLabelProvider(Set<String> symbols)
{
this.symbols = symbols;
}
@Override
public Image getColumnImage(Object element, int columnIndex)
{
return null;
}
@Override
public String getColumnText(Object element, int columnIndex)
{
ResultItem item = (ResultItem) element;
switch (columnIndex)
{
case 0:
return item.getSymbol();
case 1:
return item.getName();
case 2:
return item.getIsin();
case 3:
if (item.getLastTrade() != 0)
return Values.Quote.format(item.getLastTrade());
else
return null;
case 4:
return item.getType();
case 5:
return item.getExchange();
default:
throw new IllegalArgumentException(String.valueOf(columnIndex));
}
}
@Override
public Color getForeground(Object element, int columnIndex)
{
ResultItem item = (ResultItem) element;
if (item.getSymbol() == null)
return Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GRAY);
else if (symbols.contains(item.getSymbol()))
return Display.getCurrent().getSystemColor(SWT.COLOR_GRAY);
else
return null;
}
@Override
public Color getBackground(Object element, int columnIndex)
{
return null;
}
}
}