package name.abuchen.portfolio.ui.views.columns; import java.text.MessageFormat; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Shell; import name.abuchen.portfolio.model.Adaptor; import name.abuchen.portfolio.model.Classification; import name.abuchen.portfolio.model.InvestmentVehicle; import name.abuchen.portfolio.model.Taxonomy; import name.abuchen.portfolio.ui.Messages; import name.abuchen.portfolio.ui.util.viewers.Column; import name.abuchen.portfolio.ui.util.viewers.ColumnViewerSorter; import name.abuchen.portfolio.ui.util.viewers.OptionLabelProvider; public class TaxonomyColumn extends Column { private static final class TaxonomyOptions implements Options<Integer> { private final Taxonomy taxonomy; private TaxonomyOptions(Taxonomy taxonomy) { this.taxonomy = taxonomy; } @Override public List<Integer> getOptions() { // 1 --> skip taxonomy root node List<Integer> elements = IntStream.range(1, taxonomy.getHeigth()) // NOSONAR .boxed().collect(Collectors.toList()); elements.add(SHOW_FULL_CLASSIFICATION); return elements; } @Override public Integer valueOf(String s) { return Integer.parseInt(s); } @Override public String toString(Integer option) { return option.toString(); } @Override public String getColumnLabel(Integer option) { int index = option; if (index == SHOW_FULL_CLASSIFICATION) return taxonomy.getName(); List<String> labels = taxonomy.getDimensions(); return labels != null && index < labels.size() ? labels.get(index - 1) : MessageFormat.format(Messages.LabelLevelNameNumber, taxonomy.getName(), option); } @Override public String getMenuLabel(Integer option) { int index = option; if (index == SHOW_FULL_CLASSIFICATION) return Messages.LabelFullClassification; List<String> labels = taxonomy.getDimensions(); return labels != null && index <= labels.size() ? labels.get(index - 1) : MessageFormat.format(Messages.LabelLevelNumber, option); } @Override public String getDescription(Integer option) { return null; } @Override public boolean canCreateNewOptions() { return false; } @Override public Integer createNewOption(Shell shell) { throw new UnsupportedOperationException(); } } private static final class TaxonomyLabelProvider extends OptionLabelProvider<Integer> { private final Taxonomy taxonomy; public TaxonomyLabelProvider(Taxonomy taxonomy) { this.taxonomy = taxonomy; } @Override public String getText(Object e, Integer option) { InvestmentVehicle vehicle = Adaptor.adapt(InvestmentVehicle.class, e); if (vehicle == null) return null; List<Classification> classifications = taxonomy.getClassifications(vehicle); if (classifications.isEmpty()) return null; StringBuilder answer = new StringBuilder(); for (Classification c : classifications) { if (answer.length() > 0) answer.append(", "); //$NON-NLS-1$ if (option == SHOW_FULL_CLASSIFICATION) { answer.append(c.getPathName(false)); } else { List<Classification> path = c.getPathToRoot(); if (option < path.size()) answer.append(path.get(option).getName()); } } return answer.toString(); } } private static final int SHOW_FULL_CLASSIFICATION = 100; public TaxonomyColumn(final Taxonomy taxonomy) { super(taxonomy.getId(), taxonomy.getName(), SWT.LEFT, 120); TaxonomyLabelProvider labelProvider = new TaxonomyLabelProvider(taxonomy); setGroupLabel(Messages.ColumnTaxonomy); setOptions(new TaxonomyOptions(taxonomy)); setLabelProvider(labelProvider); setComparator(new TaxonomyComparator(labelProvider)); } private class TaxonomyComparator implements Comparator<Object> { private final TaxonomyLabelProvider labelProvider; public TaxonomyComparator(TaxonomyLabelProvider labelProvider) { this.labelProvider = labelProvider; } @Override public int compare(Object o1, Object o2) { Integer option = (Integer) ColumnViewerSorter.SortingContext.getColumnOption(); String s1 = labelProvider.getText(o1, option); String s2 = labelProvider.getText(o2, option); if (s1 == null && s2 == null) return 0; else if (s1 == null) return -1; else if (s2 == null) return 1; return s1.compareToIgnoreCase(s2); } } }