/*******************************************************************************
* Copyright (c) 2007, 2010 Association for Decentralized Information Management
* in Industry THTH ry.
* 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:
* VTT Technical Research Centre of Finland - initial API and implementation
*******************************************************************************/
/*
* 4.7.2006
*/
package org.simantics.utils.ui.workbench.ui;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.TreeViewer;
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.widgets.TreeColumn;
import org.eclipse.ui.IMemento;
/**
* This class adds column sorting functionality to SWT Tree widget.
*
* Attach this Sorter after you have created all columns.
*
* Usage: TreeColumnSorter.attachTreeColumnSorter(myTree);
*
* @author Toni Kalajainen
*/
public class TreeColumnSorter {
/** The tree */
protected final TreeViewer viewer;
/** the sorter */
protected final ColumnSorter sorter;
/** column specific comparators*/
protected Map> columnComparators =
new HashMap>();
public static TreeColumnSorter attachTreeColumnSorter(TreeViewer viewer) {
return new TreeColumnSorter(viewer);
}
public static void unattachTreeColumnSorter(TreeViewer viewer) {
viewer.setSorter(null);
}
private TreeColumnSorter(TreeViewer viewer) {
this.viewer = viewer;
this.sorter = new ColumnSorter();
// Attach columns
TreeColumn columns[] = viewer.getTree().getColumns();
for(int i=0; i comparator)
{
columnComparators.put(index, comparator);
viewer.refresh();
}
public void setColumnAscending(int index)
{
sorter.setIndex(index);
sorter.setAscending(true);
viewer.refresh();
}
private final static String PRI_ASC = "TPriAsc";
private final static String SEC_ASC = "TSecAsc";
private final static String PRI_IND = "TPriInd";
private final static String SEC_IND = "TSecInd";
public void saveState(String id, IMemento memento) {
memento.putInteger(id+PRI_ASC, sorter.isAscending()?1:0);
memento.putInteger(id+SEC_ASC, sorter.isSecondaryAscending()?1:0);
memento.putInteger(id+PRI_IND, sorter.getIndex());
memento.putInteger(id+SEC_IND, sorter.getSecondaryIndex());
}
public void restoreState(String id, IMemento memento) {
if (!hasState(id, memento)) return;
sorter.setAscending( memento.getInteger(id+PRI_ASC)==1 );
sorter.setSecondaryAscending( memento.getInteger(id+SEC_ASC)==1 );
sorter.setIndex( memento.getInteger(id+PRI_IND) );
sorter.setSecondaryIndex( memento.getInteger(id+SEC_IND) );
viewer.refresh();
}
public boolean hasState(String id, IMemento memento) {
return (memento.getInteger(id+PRI_ASC)==null) &&
(memento.getInteger(id+SEC_ASC)==null) &&
(memento.getInteger(id+PRI_IND)==null) &&
(memento.getInteger(id+SEC_IND)==null);
}
class ColumnSorter extends ViewerSorter {
/** Sort direction */
private boolean ascending = true;
/** Secondary Sort direction */
private boolean secondaryAscending = true;
/** Sort column */
private int columnIndex = 0;
/** Secondary sort column */
private int secondaryColumnIndex = -1;
/** case sensitive */
private boolean caseSensitive = false;
public void setAscending(boolean ascending) {
this.ascending = ascending;
}
public boolean isAscending() {
return ascending;
}
public void setSecondaryAscending(boolean ascending) {
this.secondaryAscending = ascending;
}
public boolean isSecondaryAscending() {
return secondaryAscending;
}
public void setIndex(int index) {
this.columnIndex = index;
}
public int getIndex() {
return columnIndex;
}
public void setSecondaryIndex(int index) {
this.secondaryColumnIndex = index;
}
public int getSecondaryIndex() {
return secondaryColumnIndex;
}
@SuppressWarnings("unchecked")
private int compare(int columnIndex, String text1, String text2, Object o1, Object o2)
{
@SuppressWarnings("rawtypes")
Comparator c = columnComparators.get(columnIndex);
if (c==null || o1==null || o2==null)
return text1.compareTo(text2);
return c.compare(o1, o2);
}
public int compare(Viewer viewer, Object e1, Object e2) {
int result = 0;
TreeViewer v = (TreeViewer) viewer;
IBaseLabelProvider blp = v.getLabelProvider();
if (!(blp instanceof ITableLabelProvider)) {
return super.compare(viewer, e1, e2);
}
ITableLabelProvider tlp = (ITableLabelProvider) blp;
// Primary sort
String text1 = tlp.getColumnText(e1, columnIndex);
String text2 = tlp.getColumnText(e2, columnIndex);
if (text1==null) text1="";
if (text2==null) text2="";
if (!caseSensitive) {
text1 = text1.toLowerCase();
text2 = text2.toLowerCase();
}
result = compare(columnIndex, text1, text2, e1, e2);
if (!ascending) return -result;
// secondary sort
if (result==0 && (secondaryColumnIndex>=0)) {
text1 = tlp.getColumnText(e1, secondaryColumnIndex);
text2 = tlp.getColumnText(e2, secondaryColumnIndex);
if (text1==null) text1="";
if (text2==null) text2="";
if (!caseSensitive) {
text1 = text1.toLowerCase();
text2 = text2.toLowerCase();
}
result = compare(secondaryColumnIndex, text1, text2, e1, e2);
if (!secondaryAscending) return -result;
}
return result;
}
public boolean isCaseSensitive() {
return caseSensitive;
}
public void setCaseSensitive(boolean caseSensitive) {
this.caseSensitive = caseSensitive;
}
}
public ColumnSorter getSorter() {
return sorter;
}
}