/******************************************************************************* * 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; } }