| /******************************************************************************* |
| * Copyright (c) 2000, 2003 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-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(); |
| } |
| } |
| |
| } |