/**
* Copyright (c) 2010, 2013 Darmstadt University of Technology.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Olav Lenz - initial API and implementation
*/
package org.eclipse.recommenders.rcp.utils;
import java.util.Comparator;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.TableColumn;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
public final class TableSortConfigurator {
private final TableViewer tableViewer;
private final IAction refreshUiAction;
private final Map<TableColumn, Comparator<Object>> comparators = Maps.newHashMap();
private TableColumn initialSortingColumn = null;
private int initialDirection = SWT.UP;
private TableSortConfigurator(TableViewer tableViewer, IAction refreshUiAction) {
this.tableViewer = tableViewer;
this.refreshUiAction = refreshUiAction;
}
public static TableSortConfigurator newConfigurator(TableViewer tableViewer, IAction refreshAction) {
return new TableSortConfigurator(tableViewer, refreshAction);
}
public TableSortConfigurator add(TableColumn tableColoumn, Comparator<Object> comparator) {
comparators.put(tableColoumn, comparator);
return this;
}
public TableSortConfigurator initialize(TableColumn tableColoumn, int direction) {
this.initialSortingColumn = tableColoumn;
this.initialDirection = direction;
return this;
}
public void configure() {
TableComparator comparator = new TableComparator(tableViewer, refreshUiAction, ImmutableMap.copyOf(comparators));
tableViewer.setComparator(comparator);
for (Entry<TableColumn, Comparator<Object>> entry : comparators.entrySet()) {
entry.getKey().addSelectionListener(new SelectionListener(entry.getKey(), comparator));
}
if (initialSortingColumn != null) {
tableViewer.getTable().setSortDirection(initialDirection);
comparator.initial(initialSortingColumn, initialDirection);
tableViewer.getTable().setSortColumn(initialSortingColumn);
refreshUiAction.run();
}
}
}
class TableComparator extends ViewerComparator {
private final ImmutableMap<TableColumn, Comparator<Object>> comparators;
private final TableViewer tableViewer;
private final IAction refreshUiAction;
private int direction = SWT.UP;
private TableColumn tableColumn = null;
public TableComparator(final TableViewer tableViewer, final IAction refreshUiAction,
final ImmutableMap<TableColumn, Comparator<Object>> comparators) {
this.tableViewer = tableViewer;
this.refreshUiAction = refreshUiAction;
this.comparators = comparators;
}
public void initial(final TableColumn tableColumn, final int direction) {
this.tableColumn = tableColumn;
this.direction = direction;
}
public void sort(final TableColumn tableColumn) {
updateDirection(tableColumn);
this.tableColumn = tableColumn;
tableViewer.getTable().setSortDirection(direction);
tableViewer.getTable().setSortColumn(tableColumn);
refreshUiAction.run();
}
private void updateDirection(final TableColumn tableColumn) {
if (this.tableColumn == null || !this.tableColumn.equals(tableColumn)) {
direction = SWT.UP;
} else {
toggleDirection();
}
}
private void toggleDirection() {
switch (direction) {
case SWT.NONE:
direction = SWT.UP;
break;
case SWT.UP:
direction = SWT.DOWN;
break;
case SWT.DOWN:
direction = SWT.NONE;
break;
default:
throw new AssertionError("Sort direction illegal: " + direction); //$NON-NLS-1$
}
}
@Override
public int compare(final Viewer viewer, final Object o1, final Object o2) {
if (direction == SWT.NONE) {
return 0;
}
Comparator<Object> comparator = comparators.get(tableColumn);
if (comparator == null) {
return 0;
}
return direction == SWT.DOWN ? comparator.compare(o2, o1) : comparator.compare(o1, o2);
}
}
class SelectionListener extends SelectionAdapter {
private final TableColumn tableColumn;
private final TableComparator comparator;
public SelectionListener(final TableColumn tableColumn, final TableComparator comparator) {
this.tableColumn = tableColumn;
this.comparator = comparator;
}
@Override
public void widgetSelected(final SelectionEvent e) {
comparator.sort(tableColumn);
}
}