### Eclipse Workspace Patch 1.0 #P org.eclipse.mylyn.tasks.ui Index: src/org/eclipse/mylyn/internal/tasks/ui/views/TaskListTableSorter.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/views/TaskListTableSorter.java,v retrieving revision 1.36 diff -u -r1.36 TaskListTableSorter.java --- src/org/eclipse/mylyn/internal/tasks/ui/views/TaskListTableSorter.java 29 Jan 2008 06:42:34 -0000 1.36 +++ src/org/eclipse/mylyn/internal/tasks/ui/views/TaskListTableSorter.java 24 Feb 2008 17:24:49 -0000 @@ -35,6 +35,12 @@ private SortByIndex sortByIndex = SortByIndex.PRIORITY; + private static final int DEFAULT_SORT_DIRECTION2 = 1; + + private int sortDirection2 = DEFAULT_SORT_DIRECTION2; + + private SortByIndex sortByIndex2 = SortByIndex.SUMMARY; + private final TaskListView view; private TaskKeyComparator taskKeyComparator = new TaskKeyComparator(); @@ -127,30 +133,48 @@ private int compareElements(AbstractTaskContainer element1, AbstractTaskContainer element2) { if (SortByIndex.PRIORITY.equals(sortByIndex)) { - int result = this.sortDirection * element1.getPriority().compareTo(element2.getPriority()); + int result = sortByPriority(element1, element2, sortDirection); if (result != 0) { return result; } - return sortBySummary(element1, element2); - + if (SortByIndex.DATE_CREATED.equals(sortByIndex2)) { + return sortByDate(element1, element2, sortDirection2); + } else { + if (SortByIndex.SUMMARY.equals(sortByIndex2)) { + return sortBySummary(element1, element2, sortDirection2); + } else { + return result; + } + } } else if (SortByIndex.DATE_CREATED.equals(sortByIndex)) { - AbstractTask t1 = null; - AbstractTask t2 = null; - if (element1 instanceof AbstractTask) { - t1 = (AbstractTask) element1; - } - if (element2 instanceof AbstractTask) { - t2 = (AbstractTask) element2; - } - if (t1 != null && t2 != null) { - if (t1.getCreationDate() != null) { - return t1.getCreationDate().compareTo(t2.getCreationDate()); - } + int result = sortByDate(element1, element2, sortDirection); + if (result != 0) { + return result; + } + if (SortByIndex.PRIORITY.equals(sortByIndex2)) { + return sortByPriority(element1, element2, sortDirection2); + } else { + if (SortByIndex.SUMMARY.equals(sortByIndex2)) { + return sortBySummary(element1, element2, sortDirection2); + } else { + return result; + } } } else { - return sortBySummary(element1, element2); + int result = sortBySummary(element1, element2, sortDirection); + if (result != 0) { + return result; + } + if (SortByIndex.DATE_CREATED.equals(sortByIndex2)) { + return sortByDate(element1, element2, sortDirection2); + } else { + if (SortByIndex.PRIORITY.equals(sortByIndex2)) { + return sortByPriority(element1, element2, sortDirection2); + } else { + return result; + } + } } - return 0; } /** @@ -160,9 +184,43 @@ * @param element2 * @return sort order */ - private int sortBySummary(AbstractTaskContainer element1, AbstractTaskContainer element2) { - return this.sortDirection - * taskKeyComparator.compare(getSortableFromElement(element1), getSortableFromElement(element2)); + private int sortBySummary(AbstractTaskContainer element1, AbstractTaskContainer element2, int sortDirection) { + return sortDirection * taskKeyComparator.compare(getSortableFromElement(element1), getSortableFromElement(element2)); + } + + /** + * Determine the sort order of two tasks by priority + * + * @param element1 + * @param element2 + * @return sort order + */ + private int sortByPriority(AbstractTaskContainer element1, AbstractTaskContainer element2, int sortDirection) { + return sortDirection * element1.getPriority().compareTo(element2.getPriority()); + } + + /** + * Determine the sort order of two tasks by creation date + * + * @param element1 + * @param element2 + * @return sort order + */ + private int sortByDate(AbstractTaskContainer element1, AbstractTaskContainer element2, int sortDirection) { + AbstractTask t1 = null; + AbstractTask t2 = null; + if (element1 instanceof AbstractTask) { + t1 = (AbstractTask) element1; + } + if (element2 instanceof AbstractTask) { + t2 = (AbstractTask) element2; + } + if (t1 != null && t2 != null) { + if (t1.getCreationDate() != null) { + return sortDirection * t1.getCreationDate().compareTo(t2.getCreationDate()); + } + } + return 0; } /** @@ -228,4 +286,30 @@ } } + + public SortByIndex getSortByIndex2() { + return sortByIndex2; + } + + public void setSortByIndex2(SortByIndex sortByIndex) { + SortByIndex oldValue = this.sortByIndex2; + this.sortByIndex2 = sortByIndex; + if (!oldValue.equals(sortByIndex)) { + view.getViewer().refresh(); + } + + } + + public int getSortDirection2() { + return sortDirection2; + } + + public void setSortDirection2(int sortDirection) { + int oldValue = this.sortDirection2; + this.sortDirection2 = sortDirection; + if (oldValue != this.sortDirection2) { + view.getViewer().refresh(); + } + } + } Index: src/org/eclipse/mylyn/internal/tasks/ui/views/SortyByDropDownAction.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/views/SortyByDropDownAction.java,v retrieving revision 1.7 diff -u -r1.7 SortyByDropDownAction.java --- src/org/eclipse/mylyn/internal/tasks/ui/views/SortyByDropDownAction.java 26 Nov 2007 19:31:39 -0000 1.7 +++ src/org/eclipse/mylyn/internal/tasks/ui/views/SortyByDropDownAction.java 24 Feb 2008 17:24:48 -0000 @@ -24,7 +24,7 @@ private final TaskListView taskListView; - private static final String LABEL = "Sort by"; + private static final String LABEL = "First Sort by"; private Action byPriority; Index: src/org/eclipse/mylyn/internal/tasks/ui/views/TaskListView.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.tasks.ui/src/org/eclipse/mylyn/internal/tasks/ui/views/TaskListView.java,v retrieving revision 1.233 diff -u -r1.233 TaskListView.java --- src/org/eclipse/mylyn/internal/tasks/ui/views/TaskListView.java 22 Feb 2008 02:23:51 -0000 1.233 +++ src/org/eclipse/mylyn/internal/tasks/ui/views/TaskListView.java 24 Feb 2008 17:24:50 -0000 @@ -273,7 +273,9 @@ private PriorityDropDownAction filterOnPriorityAction; - private SortyByDropDownAction sortByAction; + private SortyByDropDownAction firstSortByAction; + + private ThenSortyByDropDownAction thenSortByAction; private PresentationDropDownSelectionAction presentationDropDownSelectionAction; @@ -1080,7 +1082,8 @@ manager.add(collapseAll); manager.add(expandAll); manager.add(new Separator(ID_SEPARATOR_FILTERS)); - manager.add(sortByAction); + manager.add(firstSortByAction); + manager.add(thenSortByAction); manager.add(filterOnPriorityAction); manager.add(filterCompleteTask); //manager.add(filterArchiveCategory); @@ -1334,7 +1337,8 @@ synchronizeAutomatically = new SynchronizeAutomaticallyAction(); openPreferencesAction = new OpenTasksUiPreferencesAction(); //filterArchiveCategory = new FilterArchiveContainerAction(this); - sortByAction = new SortyByDropDownAction(this); + firstSortByAction = new SortyByDropDownAction(this); + thenSortByAction = new ThenSortyByDropDownAction(this); filterOnPriorityAction = new PriorityDropDownAction(this); linkWithEditorAction = new LinkWithEditorAction(this); presentationDropDownSelectionAction = new PresentationDropDownSelectionAction(this); @@ -1616,7 +1620,8 @@ } public void setManualFiltersEnabled(boolean enabled) { - sortByAction.setEnabled(enabled); + firstSortByAction.setEnabled(enabled); + thenSortByAction.setEnabled(enabled); filterOnPriorityAction.setEnabled(enabled); filterCompleteTask.setEnabled(enabled); //filterArchiveCategory.setEnabled(enabled); Index: src/org/eclipse/mylyn/internal/tasks/ui/views/ThenSortyByDropDownAction.java =================================================================== RCS file: src/org/eclipse/mylyn/internal/tasks/ui/views/ThenSortyByDropDownAction.java diff -N src/org/eclipse/mylyn/internal/tasks/ui/views/ThenSortyByDropDownAction.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/mylyn/internal/tasks/ui/views/ThenSortyByDropDownAction.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright (c) 2004, 2007 Mylyn project committers 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 + *******************************************************************************/ + +package org.eclipse.mylyn.internal.tasks.ui.views; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.IMenuCreator; +import org.eclipse.jface.action.Separator; +import org.eclipse.mylyn.internal.tasks.ui.TasksUiImages; +import org.eclipse.mylyn.internal.tasks.ui.views.TaskListTableSorter.SortByIndex; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Menu; + +/** + * @author Mik Kersten + */ +class ThenSortyByDropDownAction extends Action implements IMenuCreator { + + private final TaskListView taskListView; + + private static final String LABEL = "Then Sort by"; + + private Action byPriority; + + private Action bySummary; + + private Action byDateCreated; + + private Menu dropDownMenu = null; + + public ThenSortyByDropDownAction(TaskListView taskListView) { + super(); + this.taskListView = taskListView; + setText(LABEL); + setToolTipText(LABEL); + setMenuCreator(this); + } + + public void dispose() { + if (dropDownMenu != null) { + dropDownMenu.dispose(); + dropDownMenu = null; + } + } + + public Menu getMenu(Control parent) { + if (dropDownMenu != null) { + dropDownMenu.dispose(); + } + dropDownMenu = new Menu(parent); + addActionsToMenu(); + return dropDownMenu; + } + + public Menu getMenu(Menu parent) { + if (dropDownMenu != null) { + dropDownMenu.dispose(); + } + dropDownMenu = new Menu(parent); + addActionsToMenu(); + return dropDownMenu; + } + + public void addActionsToMenu() { + byPriority = new Action("", AS_CHECK_BOX) { + @Override + public void run() { + taskListView.getSorter().setSortByIndex2(SortByIndex.PRIORITY); + byPriority.setChecked(true); + bySummary.setChecked(false); + byDateCreated.setChecked(false); + } + }; + byPriority.setEnabled(true); + byPriority.setText("Priority"); + byPriority.setImageDescriptor(TasksUiImages.PRIORITY_1); + new ActionContributionItem(byPriority).fill(dropDownMenu, -1); + + bySummary = new Action("", AS_CHECK_BOX) { + @Override + public void run() { + taskListView.getSorter().setSortByIndex2(SortByIndex.SUMMARY); + byPriority.setChecked(false); + bySummary.setChecked(true); + byDateCreated.setChecked(false); + } + }; + bySummary.setEnabled(true); + bySummary.setText("Summary"); + new ActionContributionItem(bySummary).fill(dropDownMenu, -1); + + byDateCreated = new Action("", AS_CHECK_BOX) { + @Override + public void run() { + taskListView.getSorter().setSortByIndex2(SortByIndex.DATE_CREATED); + byPriority.setChecked(false); + bySummary.setChecked(false); + byDateCreated.setChecked(true); + } + }; + byDateCreated.setEnabled(true); + byDateCreated.setText("Date Created"); + byDateCreated.setImageDescriptor(TasksUiImages.CALENDAR_SMALL); + new ActionContributionItem(byDateCreated).fill(dropDownMenu, -1); + + new Separator().fill(dropDownMenu, -1); + + Action reverse = new Action("", AS_CHECK_BOX) { + @Override + public void run() { + taskListView.getSorter().setSortDirection2(taskListView.getSorter().getSortDirection() * -1); + setChecked(taskListView.getSorter().getSortDirection() < 0); + } + }; + reverse.setEnabled(true); + reverse.setText("Descending"); + reverse.setChecked(taskListView.getSorter().getSortDirection() < 0); + new ActionContributionItem(reverse).fill(dropDownMenu, -1); + + switch (taskListView.getSorter().getSortByIndex2()) { + case PRIORITY: + byPriority.setChecked(true); + break; + case SUMMARY: + bySummary.setChecked(true); + break; + case DATE_CREATED: + byDateCreated.setChecked(true); + break; + } + } + + @Override + public void run() { + this.setChecked(isChecked()); + } +} #P org.eclipse.mylyn.tasks.tests Index: src/org/eclipse/mylyn/tasks/tests/TableSorterTest.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.mylyn/org.eclipse.mylyn.tasks.tests/src/org/eclipse/mylyn/tasks/tests/TableSorterTest.java,v retrieving revision 1.16 diff -u -r1.16 TableSorterTest.java --- src/org/eclipse/mylyn/tasks/tests/TableSorterTest.java 26 Nov 2007 19:31:38 -0000 1.16 +++ src/org/eclipse/mylyn/tasks/tests/TableSorterTest.java 24 Feb 2008 17:24:55 -0000 @@ -112,4 +112,52 @@ sorter.sort(new EmptyViewer(), tasks); } + public void test2LevelSort() { + final TaskListTableSorter sorter = new TaskListTableSorter(TaskListView.getFromActivePerspective()); + final MockRepositoryTask[] tasks = new MockRepositoryTask[5]; + tasks[0] = new MockRepositoryTask("local", "4", "c"); + tasks[1] = new MockRepositoryTask("local", "1", "b"); + tasks[2] = new MockRepositoryTask("local", "11", "a"); + tasks[2].setPriority("P1"); + tasks[3] = new MockRepositoryTask("local", "3", "c"); + tasks[4] = new MockRepositoryTask("local", "5", "a"); + + // sort by PRIORITY then by SUMMARY + sorter.setSortByIndex(TaskListTableSorter.SortByIndex.PRIORITY); + sorter.setSortByIndex2(TaskListTableSorter.SortByIndex.SUMMARY); + sorter.sort(new EmptyViewer(), tasks); + assertTrue("11".equals(tasks[0].getTaskKey()) && "a".equals(tasks[0].getSummary())); + assertTrue("1".equals(tasks[1].getTaskKey()) && "b".equals(tasks[1].getSummary())); + assertTrue("3".equals(tasks[2].getTaskKey()) && "c".equals(tasks[2].getSummary())); + assertTrue("4".equals(tasks[3].getTaskKey()) && "c".equals(tasks[3].getSummary())); + assertTrue("5".equals(tasks[4].getTaskKey()) && "a".equals(tasks[4].getSummary())); + + // sort by PRIORITY then by SUMMARY descending + sorter.setSortDirection2(-1); + sorter.sort(new EmptyViewer(), tasks); + assertTrue("11".equals(tasks[0].getTaskKey()) && "a".equals(tasks[0].getSummary())); + assertTrue("1".equals(tasks[4].getTaskKey()) && "b".equals(tasks[4].getSummary())); + assertTrue("3".equals(tasks[3].getTaskKey()) && "c".equals(tasks[3].getSummary())); + assertTrue("4".equals(tasks[2].getTaskKey()) && "c".equals(tasks[2].getSummary())); + assertTrue("5".equals(tasks[1].getTaskKey()) && "a".equals(tasks[1].getSummary())); + + // sort by PRIORITY descending then by SUMMARY descending + sorter.setSortDirection(-1); + sorter.sort(new EmptyViewer(), tasks); + assertTrue("11".equals(tasks[4].getTaskKey()) && "a".equals(tasks[4].getSummary())); + assertTrue("1".equals(tasks[3].getTaskKey()) && "b".equals(tasks[3].getSummary())); + assertTrue("3".equals(tasks[2].getTaskKey()) && "c".equals(tasks[2].getSummary())); + assertTrue("4".equals(tasks[1].getTaskKey()) && "c".equals(tasks[1].getSummary())); + assertTrue("5".equals(tasks[0].getTaskKey()) && "a".equals(tasks[0].getSummary())); + + // sort by PRIORITY descending then by SUMMARY + sorter.setSortDirection2(1); + sorter.sort(new EmptyViewer(), tasks); + assertTrue("11".equals(tasks[4].getTaskKey()) && "a".equals(tasks[4].getSummary())); + assertTrue("1".equals(tasks[0].getTaskKey()) && "b".equals(tasks[0].getSummary())); + assertTrue("3".equals(tasks[1].getTaskKey()) && "c".equals(tasks[1].getSummary())); + assertTrue("4".equals(tasks[2].getTaskKey()) && "c".equals(tasks[2].getSummary())); + assertTrue("5".equals(tasks[3].getTaskKey()) && "a".equals(tasks[3].getSummary())); +} + }