/*******************************************************************************
* Copyright (c) 2004, 2009 Tasktop Technologies 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:
* Tasktop Technologies - initial API and implementation
*******************************************************************************/
package org.eclipse.mylyn.internal.tasks.ui.views;
import java.text.Collator;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
import org.eclipse.mylyn.internal.tasks.core.AbstractTaskContainer;
import org.eclipse.mylyn.internal.tasks.core.ITaskRepositoryElement;
import org.eclipse.mylyn.internal.tasks.core.RepositoryQuery;
import org.eclipse.mylyn.internal.tasks.core.ScheduledTaskContainer;
import org.eclipse.mylyn.internal.tasks.core.TaskCategory;
import org.eclipse.mylyn.internal.tasks.core.TaskGroup;
import org.eclipse.mylyn.internal.tasks.core.UncategorizedTaskContainer;
import org.eclipse.mylyn.internal.tasks.core.UnmatchedTaskContainer;
import org.eclipse.mylyn.internal.tasks.core.UnsubmittedTaskContainer;
import org.eclipse.mylyn.internal.tasks.ui.util.TaskComparator;
import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.mylyn.tasks.ui.TasksUi;
import org.eclipse.ui.IMemento;
/**
* @author Mik Kersten
*/
public class TaskListSorter extends ViewerSorter {
private static final String MEMENTO_KEY_SORTER = "sorter"; //$NON-NLS-1$
private static final String MEMENTO_KEY_GROUP_BY = "groupBy"; //$NON-NLS-1$
private static final TaskListSorter.GroupBy DEFAULT_GROUP_BY = TaskListSorter.GroupBy.NONE;
public enum GroupBy {
NONE, CATEGORY_QUERY, CATEGORY_REPOSITORY;
public String getLabel() {
switch (this) {
case NONE:
return Messages.TaskListSorter_No_Grouping;
case CATEGORY_QUERY:
return Messages.TaskListSorter_Catagory_and_Query;
case CATEGORY_REPOSITORY:
return Messages.TaskListSorter_Catagory_and_Repository;
default:
return null;
}
}
public static GroupBy valueOfLabel(String label) {
for (GroupBy value : values()) {
if (value.getLabel().equals(label)) {
return value;
}
}
return null;
}
}
private class SortElement {
private int weight;
private final String[] values = new String[3];
}
private final TaskComparator taskComparator;
private GroupBy groupBy;
private final SortElement key1;
private final SortElement key2;
public TaskListSorter() {
this.taskComparator = new TaskComparator();
this.groupBy = GroupBy.CATEGORY_QUERY;
this.key1 = new SortElement();
this.key2 = new SortElement();
}
/**
* compare - invoked when column is selected calls the actual comparison method for particular criteria
*/
@Override
public int compare(Viewer compareViewer, Object o1, Object o2) {
if (o1 instanceof AbstractTask && o2 instanceof AbstractTask) {
// sort of the tasks within the container using the setting from the Sortdialog
ITask element1 = (ITask) o1;
ITask element2 = (ITask) o2;
return compareElements(element1, element2);
} else if (o1 instanceof ScheduledTaskContainer && o2 instanceof ScheduledTaskContainer) {
// scheduled Mode compare
ScheduledTaskContainer dateRangeTaskContainer1 = (ScheduledTaskContainer) o1;
ScheduledTaskContainer dateRangeTaskContainer2 = (ScheduledTaskContainer) o2;
return dateRangeTaskContainer1.getDateRange().compareTo(dateRangeTaskContainer2.getDateRange());
} else {
updateKey(key1, o1);
updateKey(key2, o2);
if (key1.weight != key2.weight) {
return key1.weight - key2.weight < 0 ? -1 : 1;
}
int result = compare(key1.values[0], key2.values[0]);
if (result != 0) {
return result;
}
result = compare(key1.values[1], key2.values[1]);
return (result != 0) ? result : compare(key1.values[2], key2.values[2]);
}
}
private int compare(String key1, String key2) {
if (key1 == null) {
return (key2 != null) ? 1 : 0;
} else if (key2 == null) {
return -1;
}
return Collator.getInstance().compare(key1, key2);
}
private void updateKey(SortElement key, Object object) {
int weight;
if (object instanceof AbstractTask) {
weight = 0;
} else if (object instanceof UncategorizedTaskContainer) {
weight = 1;
} else if (object instanceof UnsubmittedTaskContainer) {
weight = 2;
} else if (object instanceof TaskCategory) {
weight = 3;
} else if (object instanceof RepositoryQuery) {
weight = 4;
} else if (object instanceof TaskGroup) { // support for the experimental grouping of tasks
weight = 5;
} else if (object instanceof UnmatchedTaskContainer) {
weight = 6;
} else {
weight = 99;
}
key.values[0] = ((AbstractTaskContainer) object).getSummary();
key.values[1] = null;
key.values[2] = null;
switch (groupBy) {
case NONE:
weight = 1;
break;
case CATEGORY_QUERY:
break;
case CATEGORY_REPOSITORY:
if (weight == 1) {
// keep
} else if (weight == 3) {
weight = 2;
} else {
key.values[0] = getRepositoryUrl(object);
key.values[1] = weight + ""; //$NON-NLS-1$
key.values[2] = ((AbstractTaskContainer) object).getSummary();
weight = 3;
}
break;
}
key.weight = weight;
}
private String getRepositoryUrl(Object object) {
if (object instanceof ITaskRepositoryElement) {
ITaskRepositoryElement repositoryElement = (ITaskRepositoryElement) object;
String repositoryUrl = repositoryElement.getRepositoryUrl();
TaskRepository taskRepository = TasksUi.getRepositoryManager().getRepository(
repositoryElement.getConnectorKind(), repositoryUrl);
return taskRepository != null ? taskRepository.getRepositoryLabel() : null;
}
// if (object instanceof UnsubmittedTaskContainer) {
// return ((UnsubmittedTaskContainer) object).getRepositoryUrl();
// } else if (object instanceof RepositoryQuery) {
// return ((RepositoryQuery) object).getRepositoryUrl();
// } else if (object instanceof UnmatchedTaskContainer) {
// return ((UnmatchedTaskContainer) object).getRepositoryUrl();
// }
return null;
}
private int compareElements(ITask element1, ITask element2) {
return taskComparator.compare(element1, element2);
}
@Override
public TaskComparator getComparator() {
return taskComparator;
}
public GroupBy getGroupBy() {
return groupBy;
}
public void setGroupBy(GroupBy sortByIndex) {
Assert.isNotNull(sortByIndex);
this.groupBy = sortByIndex;
}
public void restoreState(IMemento memento) {
IMemento child = memento.getChild(MEMENTO_KEY_SORTER);
if (child != null) {
getComparator().restoreState(child);
}
setGroupBy(getGroupBy(memento, MEMENTO_KEY_GROUP_BY, DEFAULT_GROUP_BY));
}
public void saveState(IMemento memento) {
IMemento child = memento.createChild(MEMENTO_KEY_SORTER);
if (child != null) {
getComparator().saveState(child);
}
memento.putString(MEMENTO_KEY_GROUP_BY, getGroupBy().name());
}
private TaskListSorter.GroupBy getGroupBy(IMemento memento, String key, TaskListSorter.GroupBy defaultValue) {
String value = memento.getString(key);
if (value != null) {
try {
return TaskListSorter.GroupBy.valueOf(value);
} catch (IllegalArgumentException e) {
// ignore
}
}
return defaultValue;
}
}