/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.ui.common.table; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerSorter; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.widgets.TableColumn; import org.teiid.designer.ui.common.UiConstants; import org.teiid.designer.ui.common.UiPlugin; /** * TableViewerSorter is a ViewerSorter for TableViewers. It automatically hooks up the TableViewer's TableColumn for selection and * decorates the columns with the appropriate icons. * * @since 8.0 */ public class TableViewerSorter extends ViewerSorter implements UiConstants.Images { /** The sorted column of the TableViewer should be sorted ascending */ public static final int ASCENDING = 0; /** The sorted column of the TableViewer should be sorted ascending */ public static final int DESCENDING = 1; private static final int UNSORT = 2; TableViewer viewer; private int sortColumn = 0; private int sortOrder = UNSORT; /** * This class handles selections of the column headers. Selection of the column header will cause resorting of the shown tasks * using that column's sorter. Repeated selection of the header will toggle sorting order (ascending versus descending). */ private SelectionListener headerListener = new SelectionAdapter() { /** * Handles the case of user selecting the header area. If the column has not been selected previously, it will set the * sorter of that column to be the current tasklist sorter. Repeated presses on the same column header will toggle sorting * order (ascending/descending). */ @Override public void widgetSelected( SelectionEvent e ) { // column selected - need to sort setSortColumn(viewer.getTable().indexOf((TableColumn)e.widget)); viewer.refresh(); } }; /** * Construct an instance of TableViewerSorter. When first displayed the table will not be sorted. * * @param tableViewer this sorter's TableViewer */ public TableViewerSorter( TableViewer tableViewer ) { this.viewer = tableViewer; setSortListener(); } /** * Construct an instance of TableViewerSorter and specify it's initial sort characteristics. * * @param tableViewer this sorter's TableViewer * @param initialColumn the initial column that should be sorted when the table is first displayed. * @param initialSortOrder the initial sort order that should be displayed when the table is first displayed. Use either * ASCENDING or DESCENDING */ public TableViewerSorter( TableViewer tableViewer, int initialColumn, int initialSortOrder ) { this(tableViewer); sortColumn = initialColumn; sortOrder = initialSortOrder; } /** * Subclasses may implement this method to adapt between the row-level element that is exposed by Table and the column-level * data that is to be sorted. The baseclass has a comparator variable <code>collator</code> which may be used to compare basic * types; for example: * <p> * <code> * collator.compare(element1.getValue(columnIndex), element2.getValue(columnIndex)); * </code> * </p> * * @param viewer * @param object1 * @param object2 * @param column * @return a positive integer if the data for element1 is greater than the data at element2, or a negative integer if the data * for element1 is less than the data at element2, or zero if they are equal. */ protected int compareColumn( final TableViewer viewer, final Object object1, final Object object2, final int column ) { return super.compare(this.viewer, object1, object2); } public void setSortListener() { TableColumn[] columns = viewer.getTable().getColumns(); for (int i = 0; i < columns.length; ++i) { columns[i].addSelectionListener(headerListener); } } public boolean isUnsorted() { return this.sortOrder == UNSORT; } void setSortColumn( int columnIndex ) { if (this.sortColumn == columnIndex) { // if this is another click on the same column, increment the sort order if (sortOrder == ASCENDING) { sortOrder = DESCENDING; } else if (sortOrder == DESCENDING) { sortOrder = UNSORT; } else { sortOrder = ASCENDING; } } else { sortOrder = ASCENDING; if (this.sortColumn >= 0) { viewer.getTable().getColumn(this.sortColumn).setImage(null); } } setImageForSortOrder(columnIndex, sortOrder); this.sortColumn = columnIndex; } private void setImageForSortOrder( int columnIndex, int sorOrder ) { switch (sortOrder) { case ASCENDING: viewer.getTable().getColumn(columnIndex).setImage(UiPlugin.getDefault().getImage(ASCENDING_ICON)); break; case DESCENDING: viewer.getTable().getColumn(columnIndex).setImage(UiPlugin.getDefault().getImage(DESCENDING_ICON)); break; default: viewer.getTable().getColumn(columnIndex).setImage(null); } } /** * @see org.eclipse.jface.viewers.ViewerSorter#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) */ @Override public int compare( Viewer viewer, Object e1, Object e2 ) { int result = 0; if (sortColumn >= 0) { // only run the collator if we are sorting if (this.sortOrder != UNSORT) { result = compareColumn((TableViewer)viewer, e1, e2, sortColumn); } if (this.sortOrder == DESCENDING) { // reverse the compare result for descending if (result > 0) { result = -1; } else if (result < 0) { result = 1; } } } setImageForSortOrder(sortColumn, sortOrder); return result; } }