1 /******************************************************************************* 2 * Copyright (c) 2014, 2019 TwelveTone LLC and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * Steven Spungin <steven@spungin.tv> - initial API and implementation, ongoing maintenance 13 *******************************************************************************/ 14 15 package org.eclipse.e4.tools.emf.ui.internal.common.component.tabs; 16 17 import java.util.ArrayList; 18 import java.util.Arrays; 19 20 import org.eclipse.jface.viewers.ColumnLabelProvider; 21 import org.eclipse.jface.viewers.TableViewer; 22 import org.eclipse.jface.viewers.TableViewerColumn; 23 import org.eclipse.jface.viewers.Viewer; 24 import org.eclipse.jface.viewers.ViewerCell; 25 import org.eclipse.jface.viewers.ViewerComparator; 26 import org.eclipse.swt.SWT; 27 import org.eclipse.swt.events.MouseEvent; 28 import org.eclipse.swt.events.SelectionEvent; 29 import org.eclipse.swt.events.SelectionListener; 30 import org.eclipse.swt.graphics.Point; 31 import org.eclipse.swt.widgets.TableColumn; 32 33 public class TableViewerUtil { 34 35 // Sorts the column by the provider's text value 36 static class ColumnLabelSorter extends TableViewerUtil.AbstractInvertableTableSorter { 37 private final TableColumn col; 38 ColumnLabelSorter(TableColumn col)39 ColumnLabelSorter(TableColumn col) { 40 this.col = col; 41 } 42 43 @Override compare(Viewer viewer, Object e1, Object e2)44 public int compare(Viewer viewer, Object e1, Object e2) { 45 final TableViewer tableViewer = (TableViewer) viewer; 46 final ColumnLabelProvider labelProvider = (ColumnLabelProvider) tableViewer.getLabelProvider(Arrays.asList( 47 tableViewer.getTable().getColumns()).indexOf(col)); 48 return labelProvider.getText(e1).compareTo(labelProvider.getText(e2)); 49 } 50 } 51 52 static abstract class InvertableSorter extends ViewerComparator { 53 @Override compare(Viewer viewer, Object e1, Object e2)54 public abstract int compare(Viewer viewer, Object e1, Object e2); 55 getInverseSorter()56 abstract InvertableSorter getInverseSorter(); 57 getSortDirection()58 public abstract int getSortDirection(); 59 } 60 61 static public abstract class AbstractInvertableTableSorter extends InvertableSorter { 62 private final InvertableSorter inverse = new InvertableSorter() { 63 64 @Override 65 public int compare(Viewer viewer, Object e1, Object e2) { 66 return -1 * AbstractInvertableTableSorter.this.compare(viewer, e1, e2); 67 } 68 69 @Override 70 InvertableSorter getInverseSorter() { 71 return AbstractInvertableTableSorter.this; 72 } 73 74 @Override 75 public int getSortDirection() { 76 return SWT.DOWN; 77 } 78 }; 79 80 @Override getInverseSorter()81 InvertableSorter getInverseSorter() { 82 return inverse; 83 } 84 85 @Override getSortDirection()86 public int getSortDirection() { 87 return SWT.UP; 88 } 89 } 90 91 static public class TableSortSelectionListener implements SelectionListener { 92 private final TableViewer viewer; 93 private final TableColumn column; 94 private final InvertableSorter sorter; 95 private final boolean keepDirection; 96 private InvertableSorter currentSorter; 97 98 /** 99 * The constructor of this listener. 100 * 101 * @param viewer the tableviewer this listener belongs to 102 * @param column the column this listener is responsible for 103 * @param sorter the sorter this listener uses 104 * @param defaultDirection the default sorting direction of this Listener. 105 * Possible values are {@link SWT#UP} and 106 * {@link SWT#DOWN} 107 * @param keepDirection if true, the listener will remember the last sorting 108 * direction of the associated column and restore it 109 * when the column is reselected. If false, the listener 110 * will use the default sorting direction 111 */ TableSortSelectionListener(TableViewer viewer, TableColumn column, AbstractInvertableTableSorter sorter, int defaultDirection, boolean keepDirection)112 public TableSortSelectionListener(TableViewer viewer, TableColumn column, AbstractInvertableTableSorter sorter, 113 int defaultDirection, boolean keepDirection) { 114 this.viewer = viewer; 115 this.column = column; 116 this.keepDirection = keepDirection; 117 this.sorter = defaultDirection == SWT.UP ? sorter : sorter.getInverseSorter(); 118 currentSorter = this.sorter; 119 120 this.column.addSelectionListener(this); 121 } 122 123 /** 124 * Chooses the column of this listener for sorting of the table. Mainly 125 * used when first initializing the table. 126 */ chooseColumnForSorting()127 public void chooseColumnForSorting() { 128 viewer.getTable().setSortColumn(column); 129 viewer.getTable().setSortDirection(currentSorter.getSortDirection()); 130 viewer.setComparator(currentSorter); 131 } 132 133 @Override widgetSelected(SelectionEvent e)134 public void widgetSelected(SelectionEvent e) { 135 InvertableSorter newSorter; 136 if (viewer.getTable().getSortColumn() == column) { 137 newSorter = ((InvertableSorter) viewer.getComparator()).getInverseSorter(); 138 } else { 139 if (keepDirection) { 140 newSorter = currentSorter; 141 } else { 142 newSorter = sorter; 143 } 144 } 145 146 currentSorter = newSorter; 147 chooseColumnForSorting(); 148 } 149 150 @Override widgetDefaultSelected(SelectionEvent e)151 public void widgetDefaultSelected(SelectionEvent e) { 152 widgetSelected(e); 153 } 154 } 155 refreshAndPack(TableViewer viewer)156 static public void refreshAndPack(TableViewer viewer) { 157 viewer.refresh(); 158 packAllColumns(viewer); 159 } 160 updateAndPack(TableViewer viewer, Object object)161 static public void updateAndPack(TableViewer viewer, Object object) { 162 viewer.update(object, null); 163 packAllColumns(viewer); 164 } 165 isColumnClicked(TableViewer viewer, MouseEvent e, TableViewerColumn tvColumn)166 public static boolean isColumnClicked(TableViewer viewer, MouseEvent e, TableViewerColumn tvColumn) { 167 boolean ret; 168 final ViewerCell cell = viewer.getCell(new Point(e.x, e.y)); 169 if (cell == null) { 170 ret = false; 171 } else { 172 final int index = Arrays.asList(viewer.getTable().getColumns()).indexOf(tvColumn.getColumn()); 173 if (index == -1) { 174 ret = false; 175 } else { 176 ret = index == cell.getColumnIndex(); 177 } 178 } 179 return ret; 180 } 181 getData(TableViewer viewer, MouseEvent e)182 public static Object getData(TableViewer viewer, MouseEvent e) { 183 final ViewerCell cell = viewer.getCell(new Point(e.x, e.y)); 184 if (cell == null) { 185 return null; 186 } 187 return cell.getElement(); 188 } 189 packAllColumns(TableViewer viewer)190 public static void packAllColumns(TableViewer viewer) { 191 for (final TableColumn col : viewer.getTable().getColumns()) { 192 col.pack(); 193 } 194 } 195 resetColumnOrder(TableViewer tvResults)196 static public void resetColumnOrder(TableViewer tvResults) { 197 final int[] order = tvResults.getTable().getColumnOrder(); 198 for (int i = 0; i < order.length; i++) { 199 order[i] = i; 200 } 201 tvResults.getTable().setColumnOrder(order); 202 } 203 getColumnsInDisplayOrder(TableViewer viewer)204 static public ArrayList<TableColumn> getColumnsInDisplayOrder(TableViewer viewer) { 205 final ArrayList<TableColumn> allCols = new ArrayList<>(Arrays.asList(viewer.getTable().getColumns())); 206 final int[] order = viewer.getTable().getColumnOrder(); 207 allCols.sort((o1, o2) -> order[allCols.indexOf(o1)] - order[allCols.indexOf(o2)]); 208 return allCols; 209 } 210 getVisibleColumnIndex(TableViewer tvResults2, TableColumn col)211 static public int getVisibleColumnIndex(TableViewer tvResults2, TableColumn col) { 212 final int createOrder = Arrays.asList(tvResults2.getTable().getColumns()).indexOf(col); 213 if (createOrder == -1) { 214 return -1; 215 } 216 return tvResults2.getTable().getColumnOrder()[createOrder]; 217 } 218 }