package damp.ekeko.snippets.gui; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.text.TextViewer; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.custom.StyleRange; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.swt.widgets.ToolItem; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.handlers.HandlerUtil; import damp.ekeko.gui.EkekoLabelProvider; import damp.ekeko.snippets.EkekoSnippetsPlugin; import damp.ekeko.snippets.data.TemplateGroup; /** * Dialog to inspect the history of a particular individual; lists all individuals it is based on * @author Tim */ public class MutationHistoryDialog extends Dialog { private String dataPath; private TextViewer templateTextArea; private TableViewer populationViewer; private EkekoLabelProvider ekekoLabelProvider; // private List<List<String>> rawData = new ArrayList<List<String>>(); private List<List<String>> data = new ArrayList<List<String>>(); private int generation; // The individual belongs to this generation private int index; // Index of the individual in the generation public MutationHistoryDialog(Shell parentShell, String dataPath, int gen, int index, String id) { super(parentShell); this.generation = gen; this.dataPath = dataPath; this.index = index; // Gather info on the selected individual and all of its prior individuals // Columns: ["Id" "Original" "Fitness" "F1" "Partial" "Operator" "Subject" "Operands"] List<String> indiv = fetchIndividualFromCsv(dataPath + generation + "/population.csv", id); String original = indiv.get(1); indiv.remove(0); indiv.remove(0); indiv.add(0, new Integer(generation).toString()); data.add(indiv); int curGen = generation - 1; while (curGen >= 0) { indiv = fetchIndividualFromCsv(dataPath + curGen + "/population.csv", original); original = indiv.get(1); indiv.remove(0); indiv.remove(0); indiv.add(0, new Integer(curGen).toString()); data.add(0,indiv); curGen = curGen - 1; } } public List<String> fetchIndividualFromCsv(String csvPath, String id) { try { FileInputStream fis = new FileInputStream(new File(csvPath)); BufferedReader br = new BufferedReader(new InputStreamReader(fis)); String line = br.readLine(); // Skip the header line int i=0; while ((line = br.readLine()) != null) { List<String> split = Arrays.asList(line.split(";")); if (split.get(0).equals(id)) { br.close(); List<String> copy = new ArrayList<String>(split); // Need to make a copy because split is immutable.. copy.add(new Integer(i).toString()); // Attach the index at the end.. return copy; } i++; } br.close(); } catch (IOException e) { e.printStackTrace();; } return null; } @Override protected Control createDialogArea(Composite parent) { Composite container = (Composite) super.createDialogArea(parent); container.setLayout(new GridLayout(1,false)); // **** Sash with population table + template view SashForm sash = new SashForm(parent, SWT.HORIZONTAL); sash.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 2)); // *** Population table ekekoLabelProvider = new EkekoLabelProvider(); populationViewer = new TableViewer(sash, SWT.BORDER | SWT.FULL_SELECTION); Table populationTable = populationViewer.getTable(); populationTable.setLinesVisible(true); populationTable.setHeaderVisible(true); TableViewerColumn[] cols = new TableViewerColumn[7]; cols[0] = addColumn(populationViewer, 0, "Gen", 35); cols[1] = addColumn(populationViewer, 1, "Fitness", 80); cols[2] = addColumn(populationViewer, 2, "F1", 80); cols[3] = addColumn(populationViewer, 3, "Partial", 100); cols[4] = addColumn(populationViewer, 4, "Operator", 160); cols[5] = addColumn(populationViewer, 5, "Subject", 160); cols[6] = addColumn(populationViewer, 6, "Operands", 160); for (int i=0; i< cols.length; i++) { final int idx = i; cols[i].setLabelProvider(new ColumnLabelProvider() { public String getText(Object element) { return ekekoLabelProvider.getText(((List<String>)element).get(idx)); } }); } populationViewer.setContentProvider(new ArrayContentProvider()); populationViewer.setInput(data); // *** Template text area templateTextArea = new TextViewer(sash, SWT.BORDER); templateTextArea.setEditable(false); templateTextArea.getTextWidget().setFont(EkekoSnippetsPlugin.getEditorFont()); populationViewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { IStructuredSelection selection = (IStructuredSelection)event.getSelection(); int i = data.indexOf(selection.getFirstElement()); onSelectIndividual(i, Integer.parseInt(data.get(i).get(7))); } }); populationViewer.setSelection(new StructuredSelection(populationViewer.getElementAt(0)),true); sash.setWeights(new int[]{3,2}); sash.forceFocus(); return container; } protected void onSelectIndividual(int gen, int i) { Object clojureTemplateGroup = TemplateEditorInput.deserializeClojureTemplateGroup(dataPath + gen + "/individual-" + i + ".ekt"); TemplateGroup templateGroup = TemplateGroup.newFromClojureGroup(clojureTemplateGroup); TemplatePrettyPrinter pp = new TemplatePrettyPrinter(templateGroup); templateTextArea.getTextWidget().setText(pp.prettyPrint()); for(StyleRange range : pp.getStyleRanges()) templateTextArea.getTextWidget().setStyleRange(range); } @Override protected void configureShell(Shell newShell) { super.configureShell(newShell); newShell.setText("Mutation history (generation " + generation + ", index " + index + ")"); } protected TableViewerColumn addColumn(TableViewer viewer, final int columnIndex, String attributeName, int width) { TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE, columnIndex); column.getColumn().setWidth(width); column.getColumn().setText(attributeName); column.getColumn().setMoveable(true); return column; } }