blob: a1315d4ca690a5c71b5b6f962e7bd620606f357d [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.ui.views.tasklist;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
/**
* This is the task list's sorter.
*/
class TaskSorter extends ViewerSorter {
private int[] priorities;
private int[] directions;
final static int ASCENDING = 1;
final static int DEFAULT_DIRECTION = 0;
final static int DESCENDING = -1;
final static int TYPE = 0;
final static int COMPLETION = 1;
final static int PRIORITY = 2;
final static int DESCRIPTION = 3;
final static int RESOURCE = 4;
final static int FOLDER = 5;
final static int LOCATION = 6;
final static int CREATION_TIME = 7;
final static int[] DEFAULT_PRIORITIES = { FOLDER, RESOURCE, LOCATION,
DESCRIPTION, TYPE, PRIORITY, COMPLETION, CREATION_TIME };
final static int[] DEFAULT_DIRECTIONS = { DESCENDING, //type
DESCENDING, //completed
DESCENDING, //priority
ASCENDING, //description
ASCENDING, //resource
ASCENDING, //folder
ASCENDING, //location
ASCENDING }; //creation time
/**
* Creates a new task sorter.
*/
public TaskSorter() {
resetState();
}
/* (non-Javadoc)
* Method declared on ViewerSorter.
*/
/**
* Compares two markers, sorting first by the main column of this sorter,
* then by subsequent columns, depending on the column sort order.
*/
public int compare(Viewer viewer, Object e1, Object e2) {
IMarker m1 = (IMarker) e1;
IMarker m2 = (IMarker) e2;
return compareColumnValue(m1, m2, 0);
}
public void setTopPriority(int priority) {
if (priority < 0 || priority >= priorities.length)
return;
int index = -1;
for (int i = 0; i < priorities.length; i++) {
if (priorities[i] == priority) {
index = i;
break;
}
}
if (index == -1) {
resetState();
return;
}
//shift the array
for (int i = index; i > 0; i--) {
priorities[i] = priorities[i - 1];
}
priorities[0] = priority;
directions[priority] = DEFAULT_DIRECTIONS[priority];
}
public int getTopPriority() {
return priorities[0];
}
public int[] getPriorities() {
return priorities;
}
public void setTopPriorityDirection(int direction) {
if (direction == DEFAULT_DIRECTION)
directions[priorities[0]] = DEFAULT_DIRECTIONS[priorities[0]];
else if (direction == ASCENDING || direction == DESCENDING)
directions[priorities[0]] = direction;
}
public int getTopPriorityDirection() {
return directions[priorities[0]];
}
public void reverseTopPriority() {
directions[priorities[0]] *= -1;
}
public void resetState() {
priorities = new int[DEFAULT_PRIORITIES.length];
System.arraycopy(DEFAULT_PRIORITIES, 0, priorities, 0,
priorities.length);
directions = new int[DEFAULT_DIRECTIONS.length];
System.arraycopy(DEFAULT_DIRECTIONS, 0, directions, 0,
directions.length);
}
/* (non-Javadoc)
* Method declared on ViewerSorter.
*/
/**
* Compares two markers, based only on the value of the specified column.
*/
private int compareColumnValue(IMarker m1, IMarker m2, int depth) {
if (depth >= priorities.length)
return 0;
int columnNumber = priorities[depth];
int direction = directions[columnNumber];
switch (columnNumber) {
case TYPE: {
/* category */
int result = getCategoryOrder(m1) - getCategoryOrder(m2);
if (result == 0)
return compareColumnValue(m1, m2, depth + 1);
return result * direction;
}
case COMPLETION: {
/* completed */
int result = getCompletedOrder(m1) - getCompletedOrder(m2);
if (result == 0)
return compareColumnValue(m1, m2, depth + 1);
return result * direction;
}
case PRIORITY: {
/* priority */
int result = getPriorityOrder(m1) - getPriorityOrder(m2);
if (result == 0)
return compareColumnValue(m1, m2, depth + 1);
return result * direction;
}
case DESCRIPTION: {
/* description */
int result = collator.compare(MarkerUtil.getMessage(m1), MarkerUtil
.getMessage(m2));
if (result == 0)
return compareColumnValue(m1, m2, depth + 1);
return result * direction;
}
case RESOURCE: {
/* resource name */
IResource r1 = m1.getResource();
IResource r2 = m2.getResource();
String n1 = r1.getName();
String n2 = r2.getName();
int result = collator.compare(n1, n2);
if (result == 0)
return compareColumnValue(m1, m2, depth + 1);
return result * direction;
}
case FOLDER: {
/* container name */
String c1 = MarkerUtil.getContainerName(m1);
String c2 = MarkerUtil.getContainerName(m2);
int result = c1.equals(c2) ? 0 : collator.compare(c1, c2);
if (result == 0)
return compareColumnValue(m1, m2, depth + 1);
return result * direction;
}
case LOCATION: {
/* line and location */
int result = compareLineAndLocation(m1, m2);
if (result == 0)
return compareColumnValue(m1, m2, depth + 1);
return result * direction;
}
case CREATION_TIME: {
/* creation time */
int result = compareCreationTime(m1, m2);
if (result == 0)
return compareColumnValue(m1, m2, depth + 1);
return result * direction;
}
default:
return 0;
}
}
/**
* Compares the creation time of two markers.
*/
private int compareCreationTime(IMarker m1, IMarker m2) {
long result;
try {
result = m1.getCreationTime() - m2.getCreationTime();
} catch (CoreException e) {
result = 0;
}
if (result > 0)
return 1;
else if (result < 0)
return -1;
return 0;
}
/**
* Compares the line number and location of the two markers.
* If line number is specified for both, this sorts first by line number (numerically),
* then by start offset (numerically), then by location (textually).
* If line number is not specified for either, this sorts by location.
* Otherwise, if only one has a line number, this sorts by the combined text for line number and location.
*/
private int compareLineAndLocation(IMarker m1, IMarker m2) {
int line1 = MarkerUtil.getLineNumber(m1);
int line2 = MarkerUtil.getLineNumber(m2);
if (line1 != -1 && line2 != -1) {
if (line1 != line2) {
return line1 - line2;
}
int start1 = MarkerUtil.getCharStart(m1);
int start2 = MarkerUtil.getCharStart(m2);
if (start1 != -1 && start2 != -1) {
if (start1 != start2) {
return start1 - start2;
}
}
String loc1 = MarkerUtil.getLocation(m1);
String loc2 = MarkerUtil.getLocation(m2);
return collator.compare(loc1, loc2);
}
if (line1 == -1 && line2 == -1) {
String loc1 = MarkerUtil.getLocation(m1);
String loc2 = MarkerUtil.getLocation(m2);
return collator.compare(loc1, loc2);
}
String loc1 = MarkerUtil.getLineAndLocation(m1);
String loc2 = MarkerUtil.getLineAndLocation(m2);
return collator.compare(loc1, loc2);
}
/**
* Returns the sort order for the given marker based on its category.
* Lower numbers appear first.
*/
private int getCategoryOrder(IMarker marker) {
if (MarkerUtil.isMarkerType(marker, IMarker.PROBLEM)) {
switch (MarkerUtil.getSeverity(marker)) {
case IMarker.SEVERITY_ERROR:
return 4;
case IMarker.SEVERITY_WARNING:
return 3;
case IMarker.SEVERITY_INFO:
return 2;
}
} else if (MarkerUtil.isMarkerType(marker, IMarker.TASK)) {
return 1;
}
return 1000;
}
/**
* Returns the sort order for the given marker based on its completion status.
* Lower numbers appear first.
*/
private int getCompletedOrder(IMarker marker) {
if (MarkerUtil.isMarkerType(marker, IMarker.TASK))
return MarkerUtil.isComplete(marker) ? 2 : 1;
return 0;
}
/**
* Returns the sort order for the given marker based on its priority.
*/
private int getPriorityOrder(IMarker marker) {
if (MarkerUtil.isMarkerType(marker, IMarker.TASK))
return MarkerUtil.getPriority(marker);
return -1;
}
public void saveState(IDialogSettings settings) {
if (settings == null)
return;
for (int i = 0; i < directions.length; i++) {
settings.put("direction" + i, directions[i]);//$NON-NLS-1$
settings.put("priority" + i, priorities[i]);//$NON-NLS-1$
}
}
public void restoreState(IDialogSettings settings) {
if (settings == null)
return;
try {
for (int i = 0; i < priorities.length; i++) {
directions[i] = settings.getInt("direction" + i);//$NON-NLS-1$
priorities[i] = settings.getInt("priority" + i);//$NON-NLS-1$
}
} catch (NumberFormatException e) {
resetState();
}
}
}