Skip to content

Commit

Permalink
Merge pull request #53 from CS2103AUG2016-T16-C3/sort-by-priority
Browse files Browse the repository at this point in the history
Let users sort tasks by priority
  • Loading branch information
varung97 committed Oct 23, 2016
2 parents 0872548 + e12578f commit d85ec35
Show file tree
Hide file tree
Showing 22 changed files with 318 additions and 34 deletions.
2 changes: 1 addition & 1 deletion src/main/java/seedu/manager/logic/Logic.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ public interface Logic {
CommandResult execute(String commandText);

/** Returns the filtered list of tasks */
ObservableList<ReadOnlyTask> getFilteredTaskList();
ObservableList<ReadOnlyTask> getSortedFilteredTaskList();

}
4 changes: 2 additions & 2 deletions src/main/java/seedu/manager/logic/LogicManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public CommandResult execute(String commandText) {
}

@Override
public ObservableList<ReadOnlyTask> getFilteredTaskList() {
return model.getFilteredTaskList();
public ObservableList<ReadOnlyTask> getSortedFilteredTaskList() {
return model.getSortedFilteredTaskList();
}
}
6 changes: 4 additions & 2 deletions src/main/java/seedu/manager/logic/commands/AddCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@ public CommandResult execute() {
try {
model.addTask(toAdd);

int targetIndex = model.getFilteredTaskList().size();
EventsCenter.getInstance().post(new JumpToListRequestEvent(targetIndex - 1));
int addedIndex = model.getIndexOfTask(toAdd);
assert addedIndex != -1;

EventsCenter.getInstance().post(new JumpToListRequestEvent(addedIndex));

return new CommandResult(String.format(MESSAGE_SUCCESS, toAdd.getAsPrettyText()));
} catch (UniqueTaskList.DuplicateTaskException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public DeleteCommand(int targetIndex) {
public CommandResult execute() {
assert model != null;

UnmodifiableObservableList<ReadOnlyTask> lastShownList = model.getFilteredTaskList();
UnmodifiableObservableList<ReadOnlyTask> lastShownList = model.getSortedFilteredTaskList();

if (lastShownList.size() < targetIndex) {
indicateAttemptToExecuteIncorrectCommand();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public DoneCommand(int targetIndex) {
public CommandResult execute() {
assert model != null;

UnmodifiableObservableList<ReadOnlyTask> lastShownList = model.getFilteredTaskList();
UnmodifiableObservableList<ReadOnlyTask> lastShownList = model.getSortedFilteredTaskList();

if (lastShownList.size() < targetIndex) {
indicateAttemptToExecuteIncorrectCommand();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public EditCommand(int targetIndex, HashMap<TaskProperties, Optional<String>> ed
public CommandResult execute() {
assert model != null;

UnmodifiableObservableList<ReadOnlyTask> lastShownList = model.getFilteredTaskList();
UnmodifiableObservableList<ReadOnlyTask> lastShownList = model.getSortedFilteredTaskList();

if (lastShownList.size() < targetIndex) {
indicateAttemptToExecuteIncorrectCommand();
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/seedu/manager/logic/commands/FindCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ public FindCommand(Set<String> keywords) {

@Override
public CommandResult execute() {
model.updateFilteredTaskList(keywords);
return new CommandResult(getMessageForTaskListShownSummary(model.getFilteredTaskList().size()));
model.updateSortedFilteredTaskList(keywords);
model.unSortSortedFilteredTaskList();
return new CommandResult(getMessageForTaskListShownSummary(model.getSortedFilteredTaskList().size()));
}

}
3 changes: 2 additions & 1 deletion src/main/java/seedu/manager/logic/commands/ListCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ public ListCommand() {}

@Override
public CommandResult execute() {
model.updateFilteredListToShowAll();
model.updateSortedFilteredListToShowAll();
model.unSortSortedFilteredTaskList();
return new CommandResult(MESSAGE_SUCCESS);
}
}
22 changes: 22 additions & 0 deletions src/main/java/seedu/manager/logic/commands/SortCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package seedu.manager.logic.commands;

public class SortCommand extends Command {

public static final String COMMAND_WORD = "sort";

public static final String MESSAGE_USAGE = COMMAND_WORD
+ ": Sorts the displayed tasks by priority, from highest to lowest. Tasks with no priority are shown last.\n"
+ "Parameters: None\n"
+ "Example: " + COMMAND_WORD;

public static final String MESSAGE_SUCCESS = "Sorted Tasks";

public SortCommand() {}

@Override
public CommandResult execute() {
model.sortSortedFilteredTaskListByPriority();
return new CommandResult(MESSAGE_SUCCESS);
}

}
3 changes: 3 additions & 0 deletions src/main/java/seedu/manager/logic/parser/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ public Command parseCommand(String userInput) {

case StorageCommand.COMMAND_WORD:
return new StorageCommand(arguments);

case SortCommand.COMMAND_WORD:
return new SortCommand();

default:
return new IncorrectCommand(MESSAGE_UNKNOWN_COMMAND);
Expand Down
26 changes: 17 additions & 9 deletions src/main/java/seedu/manager/model/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,21 @@ public interface Model {
/** Adds the given task */
void addTask(Task task) throws UniqueTaskList.DuplicateTaskException;

/** Returns the filtered task list as an {@code UnmodifiableObservableList<ReadOnlyTask>} */
UnmodifiableObservableList<ReadOnlyTask> getFilteredTaskList();

/** Updates the filter of the filtered task list to show all tasks */
void updateFilteredListToShowAll();

/** Updates the filter of the filtered task list to filter by the given keywords*/
void updateFilteredTaskList(Set<String> keywords);

/** Returns the sorted and filtered task list as an {@code UnmodifiableObservableList<ReadOnlyTask>} */
UnmodifiableObservableList<ReadOnlyTask> getSortedFilteredTaskList();

/** Updates the filter of the sorted and filtered task list to show all tasks */
void updateSortedFilteredListToShowAll();

/** Updates the filter of the sorted and filtered task list to filter by the given keywords */
void updateSortedFilteredTaskList(Set<String> keywords);

/** Sorts the sorted and filtered task list by priority */
void sortSortedFilteredTaskListByPriority();

/** Unsort the sorted and filtered task list */
void unSortSortedFilteredTaskList();

/** Returns index of task in sorted and filtered list */
int getIndexOfTask(ReadOnlyTask task);
}
40 changes: 37 additions & 3 deletions src/main/java/seedu/manager/model/ModelManager.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package seedu.manager.model;

import javafx.collections.transformation.FilteredList;
import javafx.collections.transformation.SortedList;
import seedu.manager.commons.core.ComponentManager;
import seedu.manager.commons.core.LogsCenter;
import seedu.manager.commons.core.UnmodifiableObservableList;
import seedu.manager.commons.events.model.TaskManagerChangedEvent;
import seedu.manager.commons.util.StringUtil;
import seedu.manager.model.task.ReadOnlyTask;
import seedu.manager.model.task.Task;
import seedu.manager.model.task.Task.TaskProperties;
import seedu.manager.model.task.UniqueTaskList;
import seedu.manager.model.task.UniqueTaskList.TaskNotFoundException;

Expand All @@ -23,6 +25,7 @@ public class ModelManager extends ComponentManager implements Model {

private final TaskManager taskManager;
private final FilteredList<Task> filteredTasks;
private final SortedList<Task> sortedTasks;

/**
* Initializes a ModelManager with the given TaskManager
Expand All @@ -37,6 +40,7 @@ public ModelManager(TaskManager src, UserPrefs userPrefs) {

taskManager = new TaskManager(src);
filteredTasks = new FilteredList<>(taskManager.getTasks());
sortedTasks = new SortedList<>(filteredTasks);
}

public ModelManager() {
Expand All @@ -46,6 +50,7 @@ public ModelManager() {
public ModelManager(ReadOnlyTaskManager initialData, UserPrefs userPrefs) {
taskManager = new TaskManager(initialData);
filteredTasks = new FilteredList<>(taskManager.getTasks());
sortedTasks = new SortedList<>(filteredTasks);
}

@Override
Expand Down Expand Up @@ -76,20 +81,49 @@ public synchronized void addTask(Task task) throws UniqueTaskList.DuplicateTaskE
updateFilteredListToShowAll();
indicateTaskManagerChanged();
}

//=========== Sorted and Filtered Task List Accessors ===============================================================

@Override
public UnmodifiableObservableList<ReadOnlyTask> getSortedFilteredTaskList() {
return new UnmodifiableObservableList<>(sortedTasks);
}

@Override
public void updateSortedFilteredListToShowAll() {
updateFilteredListToShowAll();
}

@Override
public void updateSortedFilteredTaskList(Set<String> keywords){
updateFilteredTaskList(new PredicateExpression(new DescQualifier(keywords)));
}

@Override
public void sortSortedFilteredTaskListByPriority() {
sortedTasks.setComparator((Task t1, Task t2) -> t1.compareProperty(t2, TaskProperties.PRIORITY));
}

@Override
public void unSortSortedFilteredTaskList() {
sortedTasks.setComparator(null);
}

@Override
public int getIndexOfTask(ReadOnlyTask task) {
return sortedTasks.indexOf(task);
}

//=========== Filtered Task List Accessors ===============================================================

@Override
public UnmodifiableObservableList<ReadOnlyTask> getFilteredTaskList() {
return new UnmodifiableObservableList<>(filteredTasks);
}

@Override
public void updateFilteredListToShowAll() {
filteredTasks.setPredicate(null);
}

@Override
public void updateFilteredTaskList(Set<String> keywords){
updateFilteredTaskList(new PredicateExpression(new DescQualifier(keywords)));
}
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/seedu/manager/model/task/Priority.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,17 @@ public boolean equals(Object other) {
|| (other instanceof Priority // instanceof handles nulls
&& this.value.equals(((Priority) other).value)); // state check
}

@Override
public int compareTo(TaskProperty other) {
assert other instanceof Priority;

if (this.value.equals(((Priority) other).value)) {
return 0;
} else if (this.value.equals(VALUES.LOW) || ((Priority) other).value.equals(VALUES.HIGH)) {
return 1;
} else {
return -1;
}
}
}
2 changes: 2 additions & 0 deletions src/main/java/seedu/manager/model/task/ReadOnlyTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,6 @@ default String getAsPrettyText() {
}
return builder.toString();
}

public int compareProperty(ReadOnlyTask other, TaskProperties property);
}
16 changes: 16 additions & 0 deletions src/main/java/seedu/manager/model/task/Task.java
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,22 @@ public boolean equals(Object other) {
|| (other instanceof ReadOnlyTask // instanceof handles nulls
&& this.isSameStateAs((ReadOnlyTask) other));
}

@Override
public int compareProperty(ReadOnlyTask other, TaskProperties property) {
assert other != null;
HashMap<TaskProperties, Optional<TaskProperty>> otherProps = other.getProperties();

if (!this.properties.get(property).isPresent() && !otherProps.get(property).isPresent()) {
return 0;
} else if (!this.properties.get(property).isPresent()) {
return 1;
} else if (!otherProps.get(property).isPresent()) {
return -1;
} else {
return this.properties.get(property).get().compareTo(otherProps.get(property).get());
}
}

@Override
public int hashCode() {
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/seedu/manager/model/task/TaskProperty.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import seedu.manager.commons.exceptions.IllegalValueException;

public abstract class TaskProperty {
public abstract class TaskProperty implements Comparable<TaskProperty> {
private static String MESSAGE_CONSTRAINTS;
private static String VALIDATION_REGEX;

Expand Down Expand Up @@ -62,4 +62,8 @@ public String toPrettyString() {
}

public abstract boolean equals(Object other);

public int compareTo(TaskProperty other) {
return -1;
}
}
2 changes: 1 addition & 1 deletion src/main/java/seedu/manager/ui/MainWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ private void setAccelerators() {
}

void fillInnerParts() {
taskListPanel = TaskListPanel.load(primaryStage, getTaskListPlaceholder(), logic.getFilteredTaskList());
taskListPanel = TaskListPanel.load(primaryStage, getTaskListPlaceholder(), logic.getSortedFilteredTaskList());
resultDisplay = ResultDisplay.load(primaryStage, getResultDisplayPlaceholder());
statusBarFooter = StatusBarFooter.load(primaryStage, getStatusbarPlaceholder(), config.getTaskManagerFilePath());
commandBox = CommandBox.load(primaryStage, getCommandBoxPlaceholder(), resultDisplay, logic);
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/guitests/EditCommandTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ public void edit() throws IllegalValueException {
private void assertEditSuccess(String editCommand, int index, TestTask editedTask, TestTask... currentList) {
commandBox.runCommand(String.format(editCommand, index));

TaskCardHandle addedCard = taskListPanel.navigateToTask(editedTask.getDesc().get().getValue());
assertMatching(editedTask, addedCard);
TaskCardHandle editedCard = taskListPanel.navigateToTask(editedTask.getDesc().get().getValue());
assertMatching(editedTask, editedCard);

TestTask[] expectedList = TestUtil.addTasksToList(TestUtil.removeTaskFromList(currentList, index), editedTask);
assertTrue(taskListPanel.isListMatching(expectedList));
Expand Down
56 changes: 56 additions & 0 deletions src/test/java/guitests/SortCommandTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package guitests;

import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

import org.junit.Test;

import guitests.guihandles.TaskCardHandle;
import javafx.collections.ObservableList;
import seedu.manager.logic.commands.SortCommand;
import seedu.manager.model.task.ReadOnlyTask;
import seedu.manager.model.task.Task.TaskProperties;
import seedu.manager.testutil.TestTask;

public class SortCommandTest extends TaskManagerGuiTest {

@Test
public void sort() {
assertSortSuccess(true);

TestTask taskToAdd = td.hotel;
commandBox.runCommand(taskToAdd.getAddCommand());

assertSortSuccess(false);

commandBox.runCommand("find CS2101");
assertSortSuccess(true);
}

private void assertSortSuccess(boolean runSortCommand) {
if (runSortCommand) {
commandBox.runCommand("sort");
}

Comparator<? super ReadOnlyTask> priorityComparator = (t1, t2) -> t1.compareProperty(t2, TaskProperties.PRIORITY);

assertTrue(isSorted(priorityComparator, taskListPanel.getListView().getItems()));

if (runSortCommand) {
assertResultMessage(SortCommand.MESSAGE_SUCCESS);
}
}

private boolean isSorted(Comparator<? super ReadOnlyTask> comparator, ObservableList<ReadOnlyTask> listToCheck) {
for (int i = 1; i < listToCheck.size(); i++) {
if (comparator.compare(listToCheck.get(i - 1), listToCheck.get(i)) > 0) {
return false;
}
}
return true;
}
}

0 comments on commit d85ec35

Please sign in to comment.