blob: 0286a90167ab7bc2417fff9af8490d739a482000 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2004 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jface.viewers;
import java.text.Collator;
import java.util.Arrays;
import java.util.Comparator;
/**
* A viewer sorter is used by a structured viewer to
* reorder the elements provided by its content provider.
* <p>
* The default <code>compare</code> method compares elements using two steps.
* The first step uses the values returned from <code>category</code>.
* By default, all elements are in the same category.
* The second level is based on a case insensitive compare of the strings obtained
* from the content viewer's label provider via <code>ILabelProvider.getText</code>.
* </p>
* <p>
* Subclasses may implement the <code>isSorterProperty</code> method;
* they may reimplement the <code>category</code> method to provide
* categorization; and they may override the <code>compare</code> methods
* to provide a totally different way of sorting elements.
* </p>
* @see IStructuredContentProvider
* @see StructuredViewer
*/
public class ViewerSorter {
/**
* The collator used to sort strings.
*/
protected Collator collator;
/**
* Creates a new viewer sorter, which uses the default collator
* to sort strings.
*/
public ViewerSorter() {
this(Collator.getInstance());
}
/**
* Creates a new viewer sorter, which uses the given collator
* to sort strings.
*
* @param collator the collator to use to sort strings
*/
public ViewerSorter(Collator collator) {
this.collator = collator;
}
/**
* Returns the category of the given element. The category is a
* number used to allocate elements to bins; the bins are arranged
* in ascending numeric order. The elements within a bin are arranged
* via a second level sort criterion.
* <p>
* The default implementation of this framework method returns
* <code>0</code>. Subclasses may reimplement this method to provide
* non-trivial categorization.
* </p>
*
* @param element the element
* @return the category
*/
public int category(Object element) {
return 0;
}
/**
* Returns a negative, zero, or positive number depending on whether
* the first element is less than, equal to, or greater than
* the second element.
* <p>
* The default implementation of this method is based on
* comparing the elements' categories as computed by the <code>category</code>
* framework method. Elements within the same category are further
* subjected to a case insensitive compare of their label strings, either
* as computed by the content viewer's label provider, or their
* <code>toString</code> values in other cases. Subclasses may override.
* </p>
*
* @param viewer the viewer
* @param e1 the first element
* @param e2 the second element
* @return a negative number if the first element is less than the
* second element; the value <code>0</code> if the first element is
* equal to the second element; and a positive number if the first
* element is greater than the second element
*/
public int compare(Viewer viewer, Object e1, Object e2) {
int cat1 = category(e1);
int cat2 = category(e2);
if (cat1 != cat2)
return cat1 - cat2;
// cat1 == cat2
String name1;
String name2;
if (viewer == null || !(viewer instanceof ContentViewer)) {
name1 = e1.toString();
name2 = e2.toString();
} else {
IBaseLabelProvider prov = ((ContentViewer) viewer)
.getLabelProvider();
if (prov instanceof ILabelProvider) {
ILabelProvider lprov = (ILabelProvider) prov;
name1 = lprov.getText(e1);
name2 = lprov.getText(e2);
} else {
name1 = e1.toString();
name2 = e2.toString();
}
}
if (name1 == null)
name1 = "";//$NON-NLS-1$
if (name2 == null)
name2 = "";//$NON-NLS-1$
return collator.compare(name1, name2);
}
/**
* Returns the collator used to sort strings.
*
* @return the collator used to sort strings
*/
public Collator getCollator() {
return collator;
}
/**
* Returns whether this viewer sorter would be affected
* by a change to the given property of the given element.
* <p>
* The default implementation of this method returns <code>false</code>.
* Subclasses may reimplement.
* </p>
*
* @param element the element
* @param property the property
* @return <code>true</code> if the sorting would be affected,
* and <code>false</code> if it would be unaffected
*/
public boolean isSorterProperty(Object element, String property) {
return false;
}
/**
* Sorts the given elements in-place, modifying the given array.
* <p>
* The default implementation of this method uses the
* java.util.Arrays#sort algorithm on the given array,
* calling <code>compare</code> to compare elements.
* </p>
* <p>
* Subclasses may reimplement this method to provide a more optimized implementation.
* </p>
*
* @param viewer the viewer
* @param elements the elements to sort
*/
public void sort(final Viewer viewer, Object[] elements) {
Arrays.sort(elements, new Comparator() {
public int compare(Object a, Object b) {
return ViewerSorter.this.compare(viewer, a, b);
}
});
}
}