package org.simantics.modeling.ui.view; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; import org.eclipse.nebula.widgets.nattable.sort.ISortModel; import org.eclipse.nebula.widgets.nattable.sort.SortDirectionEnum; import org.eclipse.nebula.widgets.nattable.sort.command.SortCommandHandler; import org.simantics.utils.strings.AlphanumComparator; public class BeanSortModel implements ISortModel { /** * Array that contains the sort direction for every column. * Needed to access the current sort state of a column. */ protected SortDirectionEnum[] sortDirections; /** * Array that contains the sorted flags for every column. * Needed to access the current sort state of a column. */ protected boolean[] sorted; /** * As this implementation only supports single column sorting, * this property contains the the column index of the column that * is currently used for sorting. * Initial value = -1 for no sort column */ protected int currentSortColumn = -1; /** * As this implementation only supports single column sorting, * this property contains the current sort direction of the column that * is currently used for sorting. */ protected SortDirectionEnum currentSortDirection = SortDirectionEnum.ASC; /** * Data list that is sorted */ private List allBeans; private List beans; private static int NUMBER_OF_COLUMNS = 7; public BeanSortModel(List allBeans, List beans) { this.allBeans = allBeans; this.beans = beans; sortDirections = new SortDirectionEnum[NUMBER_OF_COLUMNS]; Arrays.fill(sortDirections, SortDirectionEnum.NONE); sorted = new boolean[NUMBER_OF_COLUMNS]; Arrays.fill(sorted, false); //call initial sorting sort(0, SortDirectionEnum.ASC, false); } /** * As this is a simple implementation of an {@link ISortModel} and we don't * support multiple column sorting, this list returns either a list with one * entry for the current sort column or an empty list. */ @Override public List getSortedColumnIndexes() { List indexes = new ArrayList(); if (currentSortColumn > -1) { indexes.add(Integer.valueOf(currentSortColumn)); } return indexes; } /** * @return TRUE if the column with the given index is sorted at the moment. */ @Override public boolean isColumnIndexSorted(int columnIndex) { return sorted[columnIndex]; } /** * @return the direction in which the column with the given index is * currently sorted */ @Override public SortDirectionEnum getSortDirection(int columnIndex) { return sortDirections[columnIndex]; } /** * @return 0 as we don't support multiple column sorting. */ @Override public int getSortOrder(int columnIndex) { return 0; } /** * Remove all sorting */ @Override public void clear() { Arrays.fill(sortDirections, SortDirectionEnum.NONE); Arrays.fill(sorted, false); this.currentSortColumn = -1; } /** * This method is called by the {@link SortCommandHandler} in response to a sort command. * It is responsible for sorting the requested column. */ @Override public void sort(int columnIndex, SortDirectionEnum sortDirection, boolean accumulate) { if (!isColumnIndexSorted(columnIndex)) { clear(); } if (sortDirection.equals(SortDirectionEnum.NONE)) { //we don't support NONE as user action sortDirection = SortDirectionEnum.ASC; } Collections.sort(allBeans, new BeanComparator(columnIndex, sortDirection)); Collections.sort(beans, new BeanComparator(columnIndex, sortDirection)); sortDirections[columnIndex] = sortDirection; sorted[columnIndex] = sortDirection.equals(SortDirectionEnum.NONE) ? false : true; currentSortColumn = columnIndex; currentSortDirection = sortDirection; } @Override public Comparator getColumnComparator(int columnIndex) { // TODO : Hard-coded sort direction return new BeanComparator(columnIndex, SortDirectionEnum.ASC); } class BeanComparator implements Comparator { int colIdx = 0; SortDirectionEnum sortDirection; public BeanComparator(int columnIndex, SortDirectionEnum sortDirection) { this.colIdx = columnIndex; this.sortDirection = sortDirection; } int sort(Bean bean1, Bean bean2) { switch(colIdx) { case 0: return AlphanumComparator.CASE_INSENSITIVE_COMPARATOR.compare(bean1.getName(), bean2.getName()); case 1: return AlphanumComparator.CASE_INSENSITIVE_COMPARATOR.compare(bean1.getPath(), bean2.getPath()); case 2: return AlphanumComparator.CASE_INSENSITIVE_COMPARATOR.compare(bean1.getTypes(), bean2.getTypes()); case 3: return AlphanumComparator.CASE_INSENSITIVE_COMPARATOR.compare(bean1.getCreatedBy(), bean2.getCreatedBy()); case 5: return AlphanumComparator.CASE_INSENSITIVE_COMPARATOR.compare(bean1.getModifiedBy(), bean2.getModifiedBy()); case 4: return compareLong(bean1.createdAt, bean2.createdAt); case 6: return compareLong(bean1.modifiedAt, bean2.modifiedAt); } return 0; } private int compareLong(long x, long y) { return (x < y) ? -1 : ((x == y) ? 0 : 1); } @Override public int compare(Bean bean1, Bean bean2) { if(SortDirectionEnum.ASC == sortDirection) return sort(bean1, bean2); else if(SortDirectionEnum.DESC == sortDirection) return sort(bean2, bean1); return 0; } } /* (non-Javadoc) * @see org.eclipse.nebula.widgets.nattable.sort.ISortModel#getComparatorsForColumnIndex(int) */ @SuppressWarnings("rawtypes") @Override public List getComparatorsForColumnIndex(int columnIndex) { return null; } public void sortCurrent() { if(currentSortColumn < 0) return; sort(currentSortColumn, currentSortDirection, false); } }