diff --git a/docs/AboutUs.md b/docs/AboutUs.md
index e8817ee0bf71..aa805f3a4171 100644
--- a/docs/AboutUs.md
+++ b/docs/AboutUs.md
@@ -34,7 +34,7 @@ Component SME: UI
* Other major contributions:
* Initial gradle natty dependency configuration [[8360c0d](https://github.com/CS2103AUG2016-T14-C2/main/commit/8360c0d66fc55f36bed0d0e9d4c6b63186aeb590)]
* Set up initial interface for undo/redo in Command classes and implement Logic-level undo/redo [[4dfafa0](https://github.com/CS2103AUG2016-T14-C2/main/commit/4dfafa07337f731959bcd7e267e0de9a093ae285)]
- * All parsing related code for all commands [[Parser](../src/main/java/seedu/savvytasker/logic/parser)]
+ * Almost all parsing related code for all commands [[Parser](../src/main/java/seedu/savvytasker/logic/parser)]
-----
diff --git a/docs/UserGuide.md b/docs/UserGuide.md
index eb6fc76c9f68..a2594b5d230f 100644
--- a/docs/UserGuide.md
+++ b/docs/UserGuide.md
@@ -218,8 +218,8 @@ Format: `alias k/KEYWORD r/REPRESENTATION`
> Parameters | Description
> -------- | :--------
-> KEYWORD | Specifies the keyword that will be replaced when met in a command, must be a single word
-> REPRESENTATION | Specifies the text that will replace the keyword
+> KEYWORD | Specifies the keyword that will be replaced when met in a command, must be a single word.
+> REPRESENTATION | Specifies the text that will replace the keyword. Cannot contain slashes.
Examples:
* `alias k/pjm r/Project Meeting`
diff --git a/src/main/java/seedu/savvytasker/MainApp.java b/src/main/java/seedu/savvytasker/MainApp.java
index 787ff282cca2..878815f4a358 100644
--- a/src/main/java/seedu/savvytasker/MainApp.java
+++ b/src/main/java/seedu/savvytasker/MainApp.java
@@ -46,7 +46,7 @@ public class MainApp extends Application {
protected Config config;
protected UserPrefs userPrefs;
protected static MainApp instance;
-
+
public MainApp() {}
@Override
@@ -54,7 +54,7 @@ public void init() throws Exception {
logger.info("=============================[ Initializing Savvy Tasker ]===========================");
super.init();
instance = this;
-
+
config = initConfig(getApplicationParameter("config"));
storage = new StorageManager(config.getSavvyTaskerFilePath(), config.getUserPrefsFilePath());
@@ -69,8 +69,9 @@ public void init() throws Exception {
ui = new UiManager(logic, config, userPrefs);
initEventsCenter();
+
}
-
+
private String getApplicationParameter(String parameterName){
Map applicationParameters = getParameters().getNamed();
return applicationParameters.get(parameterName);
@@ -183,7 +184,7 @@ public void stop() {
System.exit(0);
}
- //@@author A0139915W
+ //@@author A0138431L
@Subscribe
public void handleSavvyTaskerSaveLocationChangedEvent(DataSavingLocationChangedEvent dslce) {
try {
diff --git a/src/main/java/seedu/savvytasker/commons/core/Config.java b/src/main/java/seedu/savvytasker/commons/core/Config.java
index 249cc84d3a8a..56b65d4bf159 100644
--- a/src/main/java/seedu/savvytasker/commons/core/Config.java
+++ b/src/main/java/seedu/savvytasker/commons/core/Config.java
@@ -17,7 +17,6 @@ public class Config {
private String savvyTaskerFilePath = "data/savvytasker.xml";
private String savvyTaskerListName = "MyTaskList";
-
public Config() {
}
@@ -61,7 +60,6 @@ public void setSavvyTaskerName(String savvyTaskerName) {
this.savvyTaskerListName = savvyTaskerName;
}
-
@Override
public boolean equals(Object other) {
if (other == this){
diff --git a/src/main/java/seedu/savvytasker/commons/events/storage/DataSavingLocationChangedEvent.java b/src/main/java/seedu/savvytasker/commons/events/storage/DataSavingLocationChangedEvent.java
index 6e92df0cf402..1f5f384e1056 100644
--- a/src/main/java/seedu/savvytasker/commons/events/storage/DataSavingLocationChangedEvent.java
+++ b/src/main/java/seedu/savvytasker/commons/events/storage/DataSavingLocationChangedEvent.java
@@ -3,7 +3,7 @@
import seedu.savvytasker.commons.events.BaseEvent;
import seedu.savvytasker.model.ReadOnlySavvyTasker;
-//@@author A0139915W
+//@@author A0138431L
/**
* Indicates a change in location of the storage
*/
diff --git a/src/main/java/seedu/savvytasker/commons/util/SmartDefaultDates.java b/src/main/java/seedu/savvytasker/commons/util/SmartDefaultDates.java
index c7206ebdf7c7..5eeac6948a67 100644
--- a/src/main/java/seedu/savvytasker/commons/util/SmartDefaultDates.java
+++ b/src/main/java/seedu/savvytasker/commons/util/SmartDefaultDates.java
@@ -8,7 +8,6 @@
//@@author A0139915W
/**
* Helper functions for handling dates.
- * @author A0139915W
*/
public class SmartDefaultDates {
@@ -28,41 +27,37 @@ public SmartDefaultDates(InferredDate startDateTime, InferredDate endDateTime) {
calendar = Calendar.getInstance();
today = Calendar.getInstance();
today.setTime(new Date());
- if (startDateTime == null && endDateTime == null) {
- // dates not being supplied, nothing to parse
- } else if (startDateTime == null && endDateTime != null) {
+ if (startDateTime == null && endDateTime != null) {
// apply smart default for endDateTime only
parseEnd(endDateTime);
} else if (startDateTime != null && endDateTime == null) {
// apply smart default for startDateTime only
parseStart(startDateTime);
- } else {
+ } else if (startDateTime != null && endDateTime != null) {
parseStartAndEnd(startDateTime, endDateTime);
}
}
/**
- * Gets the smart default for end date
+ * Gets the smart defaults for end date.
+ *
+ * If the date is not supplied, the date will default to today.
+ * If the time is not supplied, the time will default to 2359:59 on the specified date.
+ * If both date and time are not supplied, the date returned will be null.
* @param today the time now
* @param endDateTime the end time to parse
- * @return
*/
public Date getEnd(InferredDate endDateTime) {
if (endDateTime == null) return null;
calendar.setTime(endDateTime.getInferredDateTime());
if (endDateTime.isDateInferred() && endDateTime.isTimeInferred()) {
- // user didn't specify anything
// remove date field
return null;
} else if (endDateTime.isDateInferred()) {
- // date not supplied
- // defaults to today
calendar.set(Calendar.DATE, today.get(Calendar.DATE));
calendar.set(Calendar.MONTH, today.get(Calendar.MONTH));
calendar.set(Calendar.YEAR, today.get(Calendar.YEAR));
} else if (endDateTime.isTimeInferred()) {
- // time not supplied
- // defaults to 2359
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
@@ -97,7 +92,11 @@ private void parseEnd(InferredDate endDateTime) {
/**
- * Gets the smart default for start date
+ * Gets the smart default for start date.
+ *
+ * If the date is not supplied, the date will default to today.
+ * If the time is not supplied, the time will default to 0000:00 on the specified date.
+ * If both date and time are not supplied, the date returned will be null.
* @param today the time now
* @param startDateTime the start time to parse
* @return
@@ -110,14 +109,10 @@ public Date getStart(InferredDate startDateTime) {
// remove date field
return null;
} else if (startDateTime.isDateInferred()) {
- // date not supplied
- // defaults to today
calendar.set(Calendar.DATE, today.get(Calendar.DATE));
calendar.set(Calendar.MONTH, today.get(Calendar.MONTH));
calendar.set(Calendar.YEAR, today.get(Calendar.YEAR));
} else if (startDateTime.isTimeInferred()) {
- // time not supplied
- // defaults to 0000
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
@@ -148,8 +143,12 @@ private void parseStart(InferredDate startDateTime) {
/**
* Sets the starting and ending date/time based on defaults for providing both
- * start and end times
+ * start and end times.
+ *
+ * Note that this method has no restrictions on the starting and ending date/time.
+ * i.e. the starting time is later than the ending time.
* @param startDateTime start time supplied
+ * @param endDateTime end time supplied
*/
private void parseStartAndEnd(InferredDate startDateTime, InferredDate endDateTime) {
assert endDateTime.getInferredDateTime() != null;
diff --git a/src/main/java/seedu/savvytasker/logic/Logic.java b/src/main/java/seedu/savvytasker/logic/Logic.java
old mode 100644
new mode 100755
index bc55816f290a..1cf9b6cba531
--- a/src/main/java/seedu/savvytasker/logic/Logic.java
+++ b/src/main/java/seedu/savvytasker/logic/Logic.java
@@ -1,8 +1,10 @@
package seedu.savvytasker.logic;
+import java.util.Date;
+
import javafx.collections.ObservableList;
-import seedu.savvytasker.logic.commands.CommandResult;
import seedu.savvytasker.model.alias.AliasSymbol;
+import seedu.savvytasker.logic.commands.CommandResult;
import seedu.savvytasker.model.task.ReadOnlyTask;
/**
@@ -18,10 +20,23 @@ public interface Logic {
/** Returns the filtered list of tasks */
ObservableList getFilteredTaskList();
-
+
/** Returns the filtered list of alias symbol */
ObservableList getAliasSymbolList();
/** */
boolean canParseHeader(String keyword);
+
+ /** Returns the list of tasks that are overdue */
+ ObservableList getFilteredOverdueTasks();
+
+ /** Returns the list of floating tasks */
+ ObservableList getFilteredFloatingTasks();
+
+ /** Returns the list of tasks on a specific day */
+ ObservableList getFilteredDailyTasks(int i, Date date);
+
+ /** Returns the list of tasks that occur after the selected week */
+ ObservableList getFilteredUpcomingTasks(Date date);
+
}
diff --git a/src/main/java/seedu/savvytasker/logic/LogicManager.java b/src/main/java/seedu/savvytasker/logic/LogicManager.java
old mode 100644
new mode 100755
index 0225052f898d..b7c4231b2213
--- a/src/main/java/seedu/savvytasker/logic/LogicManager.java
+++ b/src/main/java/seedu/savvytasker/logic/LogicManager.java
@@ -1,13 +1,14 @@
package seedu.savvytasker.logic;
+import java.util.Date;
+import java.util.Deque;
+import java.util.LinkedList;
import java.util.List;
-import java.util.Stack;
import java.util.logging.Logger;
import com.google.common.eventbus.Subscribe;
import javafx.collections.ObservableList;
-import seedu.savvytasker.MainApp;
import seedu.savvytasker.commons.core.ComponentManager;
import seedu.savvytasker.commons.core.EventsCenter;
import seedu.savvytasker.commons.core.LogsCenter;
@@ -37,26 +38,26 @@
import seedu.savvytasker.model.alias.AliasSymbol;
import seedu.savvytasker.model.task.ReadOnlyTask;
import seedu.savvytasker.storage.Storage;
-import seedu.savvytasker.ui.Ui;
/**
* The main LogicManager of the app.
*/
public class LogicManager extends ComponentManager implements Logic {
private final Logger logger = LogsCenter.getLogger(LogicManager.class);
-
+ private final int MAX_UNDO_REDO_QUEUE_SIZE = 50;
+
private final Model model;
private final Storage storage;
private final MasterParser parser;
- private final Stack undoStack;
- private final Stack redoStack;
+ private final Deque undoDeque;
+ private final Deque redoDeque;
public LogicManager(Model model, Storage storage) {
this.model = model;
this.storage = storage;
this.parser = new MasterParser();
- this.undoStack = new Stack();
- this.redoStack = new Stack();
+ this.undoDeque = new LinkedList();
+ this.redoDeque = new LinkedList();
registerAllDefaultCommandParsers();
loadAllAliasSymbols();
@@ -89,23 +90,48 @@ else if (command.isRedo()){
}
}
else if (command.canUndo()){
- undoStack.push(command);
- redoStack.clear();
+ //@@author A0139916U
+ undoDeque.addLast(command);
+ if (undoDeque.size() > MAX_UNDO_REDO_QUEUE_SIZE) {
+ undoDeque.removeFirst();
+ }
+ redoDeque.clear();
}
//@@author
return result;
}
-
+
//@@author A0139915W
@Override
public ObservableList getFilteredTaskList() {
return model.getFilteredTaskList();
}
-
@Override
public ObservableList getAliasSymbolList() {
return parser.getAliasSymbolList();
+ }
+ //@@author
+
+ //@@author A0138431L
+ @Override
+ public ObservableList getFilteredOverdueTasks() {
+ return model.getFilteredOverdueTasks();
+ }
+
+ @Override
+ public ObservableList getFilteredFloatingTasks() {
+ return model.getFilteredFloatingTasks();
+ }
+
+ @Override
+ public ObservableList getFilteredDailyTasks(int i, Date date) {
+ return model.getFilteredDailyTasks(i, date);
+ }
+
+ @Override
+ public ObservableList getFilteredUpcomingTasks(Date date) {
+ return model.getFilteredUpcomingTasks(date);
}
//@@author
@@ -135,26 +161,34 @@ private void loadAllAliasSymbols() {
}
}
+ /**
+ * Undo last command and add it to the redo deque.
+ * @return true if undone successfully, false otherwise
+ */
private boolean undo() {
boolean undone = false;
- if (!undoStack.isEmpty()) {
- Command command = undoStack.pop();
+ if (!undoDeque.isEmpty()) {
+ Command command = undoDeque.removeLast();
command.undo();
- redoStack.push(command);
+ redoDeque.addLast(command);
undone = true;
}
return undone;
}
+ /**
+ * Redo last command and add it to undone deque.
+ * @return true if redone successfully, false otherwise
+ */
private boolean redo() {
boolean redone = false;
- if (!redoStack.isEmpty()) {
- Command command = redoStack.pop();
+ if (!redoDeque.isEmpty()) {
+ Command command = redoDeque.removeLast();
command.redo();
- undoStack.push(command);
+ undoDeque.addLast(command);
redone = true;
}
diff --git a/src/main/java/seedu/savvytasker/logic/commands/AddCommand.java b/src/main/java/seedu/savvytasker/logic/commands/AddCommand.java
index 83f6fc639954..faed3f637a21 100644
--- a/src/main/java/seedu/savvytasker/logic/commands/AddCommand.java
+++ b/src/main/java/seedu/savvytasker/logic/commands/AddCommand.java
@@ -97,11 +97,10 @@ public CommandResult execute() {
addToListOfTasksAdded(tasksAdded.toArray(new Task[tasksAdded.size()]));
}
+ // always >= 0 unless this is being run without UI.
int targetIndex = getIndexOfTask(taskAdded);
if (targetIndex >= 0) {
EventsCenter.getInstance().post(new JumpToListRequestEvent(targetIndex));
- } else {
- // GUI should never ever get here
}
return new CommandResult(String.format(MESSAGE_SUCCESS, toAdd));
} catch (InvalidDateException ex) {
diff --git a/src/main/java/seedu/savvytasker/logic/commands/ClearCommand.java b/src/main/java/seedu/savvytasker/logic/commands/ClearCommand.java
index e30b49e73b84..a59f2f1b0377 100644
--- a/src/main/java/seedu/savvytasker/logic/commands/ClearCommand.java
+++ b/src/main/java/seedu/savvytasker/logic/commands/ClearCommand.java
@@ -12,9 +12,6 @@ public class ClearCommand extends ModelRequiringCommand {
public static final String MESSAGE_SUCCESS = "Savvy Tasker has been cleared!";
private ReadOnlySavvyTasker original;
-
- public ClearCommand() {}
-
@Override
public CommandResult execute() {
diff --git a/src/main/java/seedu/savvytasker/logic/commands/ExitCommand.java b/src/main/java/seedu/savvytasker/logic/commands/ExitCommand.java
index 6e099ee4045f..c92f09110fa3 100644
--- a/src/main/java/seedu/savvytasker/logic/commands/ExitCommand.java
+++ b/src/main/java/seedu/savvytasker/logic/commands/ExitCommand.java
@@ -12,8 +12,6 @@ public class ExitCommand extends Command {
public static final String MESSAGE_EXIT_ACKNOWLEDGEMENT = "Exiting Savvy Tasker as requested ...";
- public ExitCommand() {}
-
@Override
public CommandResult execute() {
EventsCenter.getInstance().post(new ExitAppRequestEvent());
diff --git a/src/main/java/seedu/savvytasker/logic/commands/FindCommand.java b/src/main/java/seedu/savvytasker/logic/commands/FindCommand.java
index e9a4acac6b13..43b3b0d1ae63 100644
--- a/src/main/java/seedu/savvytasker/logic/commands/FindCommand.java
+++ b/src/main/java/seedu/savvytasker/logic/commands/FindCommand.java
@@ -5,7 +5,6 @@
/**
* Finds and lists all persons in address book whose name contains any of the argument keywords.
* Keyword matching is case sensitive.
- * @author A0139915W
*/
public class FindCommand extends ModelRequiringCommand {
diff --git a/src/main/java/seedu/savvytasker/logic/commands/HelpCommand.java b/src/main/java/seedu/savvytasker/logic/commands/HelpCommand.java
index 15e2a40c1644..b9d73365693c 100644
--- a/src/main/java/seedu/savvytasker/logic/commands/HelpCommand.java
+++ b/src/main/java/seedu/savvytasker/logic/commands/HelpCommand.java
@@ -16,8 +16,6 @@ public class HelpCommand extends Command {
public static final String SHOWING_HELP_MESSAGE = "Opened help window.";
- public HelpCommand() {}
-
@Override
public CommandResult execute() {
EventsCenter.getInstance().post(new ShowHelpRequestEvent());
diff --git a/src/main/java/seedu/savvytasker/logic/commands/ListCommand.java b/src/main/java/seedu/savvytasker/logic/commands/ListCommand.java
index f8c39d9032af..5c8f960bbb68 100644
--- a/src/main/java/seedu/savvytasker/logic/commands/ListCommand.java
+++ b/src/main/java/seedu/savvytasker/logic/commands/ListCommand.java
@@ -24,7 +24,6 @@ public class ListCommand extends ModelRequiringCommand {
//@@author A0139915W
/**
* Creates the List command to list the specified tasks
- * @author A0139915W
* @param commandModel Arguments for the List command, must not be null
*/
public ListCommand(ListType listType) {
@@ -43,9 +42,6 @@ public CommandResult execute() {
// specifies to show the alias
switch (_listType)
{
- case DueDate:
- model.updateFilteredListToShowActiveSortedByDueDate();
- break;
case PriorityLevel:
model.updateFilteredListToShowActiveSortedByPriorityLevel();
break;
@@ -55,10 +51,13 @@ public CommandResult execute() {
case Alias:
EventsCenter.getInstance().post(new ChangeListRequestEvent(DisplayedList.Alias));
break;
- default:
- // nothing to do
+ case DueDate:
+ // fall through.
+ default: // shows lists sorted by due date by default
+ model.updateFilteredListToShowActiveSortedByDueDate();
break;
}
+
if (_listType != ListType.Alias) {
EventsCenter.getInstance().post(new ChangeListRequestEvent(DisplayedList.Task));
return new CommandResult(getMessageForTaskListShownSummary(model.getFilteredTaskList().size()));
diff --git a/src/main/java/seedu/savvytasker/logic/commands/ModifyCommand.java b/src/main/java/seedu/savvytasker/logic/commands/ModifyCommand.java
index 02438849d7a4..1b5358706a60 100644
--- a/src/main/java/seedu/savvytasker/logic/commands/ModifyCommand.java
+++ b/src/main/java/seedu/savvytasker/logic/commands/ModifyCommand.java
@@ -29,7 +29,6 @@ public class ModifyCommand extends ModelRequiringCommand {
public static final String MESSAGE_DUPLICATE_TASK = "This task already exists in the task list";
private Task originalTask;
- private Task replacement;
private final int index;
private final String taskName;
private final InferredDate startDateTime;
@@ -73,7 +72,7 @@ public CommandResult execute() {
}
ReadOnlyTask taskToModify = lastShownList.get(index - 1);
- replacement = new Task(taskToModify, taskName, startDateTime,
+ Task replacement = new Task(taskToModify, taskName, startDateTime,
endDateTime, location, priority,
recurringType, numberOfRecurrence,
category, description);
@@ -81,11 +80,11 @@ public CommandResult execute() {
try {
originalTask = (Task)taskToModify;
Task taskModified = model.modifyTask(taskToModify, replacement);
+
+ // GUI will always get index >= 0;
int targetIndex = getIndexOfTask(taskModified);
if (targetIndex >= 0) {
EventsCenter.getInstance().post(new JumpToListRequestEvent(targetIndex));
- } else {
- // GUI should never ever get here
}
} catch (TaskNotFoundException e) {
assert false : "The target task cannot be missing";
diff --git a/src/main/java/seedu/savvytasker/logic/commands/RedoCommand.java b/src/main/java/seedu/savvytasker/logic/commands/RedoCommand.java
index 765b3852c516..39721d6e3321 100644
--- a/src/main/java/seedu/savvytasker/logic/commands/RedoCommand.java
+++ b/src/main/java/seedu/savvytasker/logic/commands/RedoCommand.java
@@ -10,8 +10,6 @@ public class RedoCommand extends Command {
public static final String MESSAGE_REDO_ACKNOWLEDGEMENT = "Last command redone";
- public RedoCommand() {}
-
@Override
public CommandResult execute() {
return new CommandResult(MESSAGE_REDO_ACKNOWLEDGEMENT);
diff --git a/src/main/java/seedu/savvytasker/logic/commands/StorageCommand.java b/src/main/java/seedu/savvytasker/logic/commands/StorageCommand.java
index 45df445e3f37..cc3172379958 100644
--- a/src/main/java/seedu/savvytasker/logic/commands/StorageCommand.java
+++ b/src/main/java/seedu/savvytasker/logic/commands/StorageCommand.java
@@ -4,6 +4,8 @@
import seedu.savvytasker.commons.events.storage.DataSavingLocationChangedEvent;
import seedu.savvytasker.model.ReadOnlySavvyTasker;
+
+//@@author A0138431L
/**
* Changes the storage location of Savvy Tasker
*/
diff --git a/src/main/java/seedu/savvytasker/logic/commands/UndoCommand.java b/src/main/java/seedu/savvytasker/logic/commands/UndoCommand.java
index ec905685594c..125e9305bebf 100644
--- a/src/main/java/seedu/savvytasker/logic/commands/UndoCommand.java
+++ b/src/main/java/seedu/savvytasker/logic/commands/UndoCommand.java
@@ -10,8 +10,6 @@ public class UndoCommand extends Command {
public static final String MESSAGE_UNDO_ACKNOWLEDGEMENT = "Last command undone";
- public UndoCommand() {}
-
@Override
public CommandResult execute() {
return new CommandResult(MESSAGE_UNDO_ACKNOWLEDGEMENT);
diff --git a/src/main/java/seedu/savvytasker/logic/parser/AddCommandParser.java b/src/main/java/seedu/savvytasker/logic/parser/AddCommandParser.java
index 66dc288eeedf..afd504f48a72 100644
--- a/src/main/java/seedu/savvytasker/logic/parser/AddCommandParser.java
+++ b/src/main/java/seedu/savvytasker/logic/parser/AddCommandParser.java
@@ -1,4 +1,5 @@
//@@author A0139916U
+// Please see CommandParser interface for documentation for many of the overridden methods
package seedu.savvytasker.logic.parser;
import java.util.regex.Matcher;
diff --git a/src/main/java/seedu/savvytasker/logic/parser/AliasCommandParser.java b/src/main/java/seedu/savvytasker/logic/parser/AliasCommandParser.java
index 2d5240d3534d..9166b8903414 100644
--- a/src/main/java/seedu/savvytasker/logic/parser/AliasCommandParser.java
+++ b/src/main/java/seedu/savvytasker/logic/parser/AliasCommandParser.java
@@ -53,9 +53,10 @@ public AliasCommand parse(String commandText) throws ParseException {
private String parseRepresentation(String originalText) throws ParseException {
String trimmedText = originalText.trim();
- if (trimmedText.isEmpty())
+ if (trimmedText.isEmpty()) {
throw new ParseException(trimmedText, "REPRESENTATION: Needs to be at least one character!");
-
+ }
+
return trimmedText;
}
diff --git a/src/main/java/seedu/savvytasker/logic/parser/DateParser.java b/src/main/java/seedu/savvytasker/logic/parser/DateParser.java
index 66549fd40200..42ff9b2448d8 100644
--- a/src/main/java/seedu/savvytasker/logic/parser/DateParser.java
+++ b/src/main/java/seedu/savvytasker/logic/parser/DateParser.java
@@ -76,16 +76,16 @@ public InferredDate parseSingle(String input) throws ParseException {
List dateGroups = this.nattyParser.parse(input);
int totalDates = countDates(dateGroups);
- if (totalDates == 0)
+ if (totalDates == 0) {
throw new ParseException(input, "Failed to understand given date.");
+ }
- if (totalDates > 1)
+ if (totalDates > 1) {
throw new ParseException(input, "Too many dates entered.");
+ }
DateGroup group = dateGroups.get(0);
-
-
return new InferredDate(
group.getDates().get(0),
group.isDateInferred(),
diff --git a/src/main/java/seedu/savvytasker/logic/parser/FindCommandParser.java b/src/main/java/seedu/savvytasker/logic/parser/FindCommandParser.java
index 613378b1a794..d5c6867219b5 100644
--- a/src/main/java/seedu/savvytasker/logic/parser/FindCommandParser.java
+++ b/src/main/java/seedu/savvytasker/logic/parser/FindCommandParser.java
@@ -50,8 +50,9 @@ public FindCommand parse(String commandText) throws ParseException {
//@@author
private FindType parseFindType(String findTypeText) throws ParseException {
- if (findTypeText == null)
+ if (findTypeText == null) {
return null;
+ }
String trimmedFindTypeText = findTypeText.trim();
try {
@@ -67,12 +68,17 @@ private String[] parseKeywords(String keywordsBefore, String keywordsAfter) thro
String[] keywordsArr1 = new String[0];
String[] keywordsArr2 = new String[0];
- if (!trimmedKeywordsBefore.isEmpty()) keywordsArr1 = trimmedKeywordsBefore.split("\\s+");
- if (!trimmedKeywordsAfter.isEmpty()) keywordsArr2 = trimmedKeywordsAfter.split("\\s+");
+ if (!trimmedKeywordsBefore.isEmpty()) {
+ keywordsArr1 = trimmedKeywordsBefore.split("\\s+");
+ }
+ if (!trimmedKeywordsAfter.isEmpty()) {
+ keywordsArr2 = trimmedKeywordsAfter.split("\\s+");
+ }
- if (keywordsArr1.length == 0 && keywordsArr2.length == 0)
+ if (keywordsArr1.length == 0 && keywordsArr2.length == 0) {
throw new ParseException(trimmedKeywordsBefore + " ... " + trimmedKeywordsAfter,
"KEYWORD: Need to specify at least one keyword!");
+ }
return concatArray(keywordsArr1, keywordsArr2);
}
diff --git a/src/main/java/seedu/savvytasker/logic/parser/IndexParser.java b/src/main/java/seedu/savvytasker/logic/parser/IndexParser.java
index 3bdfebaea962..866ee418e60e 100644
--- a/src/main/java/seedu/savvytasker/logic/parser/IndexParser.java
+++ b/src/main/java/seedu/savvytasker/logic/parser/IndexParser.java
@@ -26,15 +26,17 @@ public int parseSingle(String indexText) throws ParseException {
try {
index = Integer.parseInt(trimmedIndexText);
- if (index <= 0)
+ if (index <= 0) {
parseError = true;
+ }
} catch (NumberFormatException ex) {
parseError = true;
}
- if (parseError)
+ if (parseError) {
throw new ParseException(trimmedIndexText, "Must be a positive whole number.");
-
+ }
+
return index;
}
@@ -66,9 +68,10 @@ public int[] parseMultiple(String indicesText) throws ParseException {
parseError = true;
}
- if (parseError)
+ if (parseError) {
throw new ParseException(trimmedIndicesText, INDEX_MUST_BE_POSITIVE);
-
+ }
+
return indices;
}
}
diff --git a/src/main/java/seedu/savvytasker/logic/parser/ListCommandParser.java b/src/main/java/seedu/savvytasker/logic/parser/ListCommandParser.java
index ad2457b96f2f..f484abc8cb9c 100644
--- a/src/main/java/seedu/savvytasker/logic/parser/ListCommandParser.java
+++ b/src/main/java/seedu/savvytasker/logic/parser/ListCommandParser.java
@@ -42,8 +42,9 @@ public ListCommand parse(String commandText) throws ParseException {
}
private ListType parseListType(String listTypeText) throws ParseException {
- if (listTypeText == null)
+ if (listTypeText == null) {
return null;
+ }
try {
listTypeText = listTypeText.trim();
diff --git a/src/main/java/seedu/savvytasker/logic/parser/MasterParser.java b/src/main/java/seedu/savvytasker/logic/parser/MasterParser.java
index 271cb564acd5..77ba0d698247 100644
--- a/src/main/java/seedu/savvytasker/logic/parser/MasterParser.java
+++ b/src/main/java/seedu/savvytasker/logic/parser/MasterParser.java
@@ -149,8 +149,9 @@ private String preprocessBody(String bodyText) {
String spaces = matcher.group(2); // Preserves the amount of spaces as that may be what user wants
AliasSymbol symbol = aliasingSymbols.get(keyword);
- if (symbol != null)
+ if (symbol != null) {
keyword = symbol.getRepresentation();
+ }
builder.append(keyword);
builder.append(spaces);
@@ -176,10 +177,12 @@ private String preprocessBody(String bodyText) {
public boolean registerCommandParser(CommandParser extends Command> commandParser) {
assert commandParser != null;
- if (commandParsers.containsKey(commandParser.getHeader()))
+ if (commandParsers.containsKey(commandParser.getHeader())) {
return false;
- if (aliasingSymbols.containsKey(commandParser.getHeader()))
+ }
+ if (aliasingSymbols.containsKey(commandParser.getHeader())) {
return false;
+ }
commandParsers.put(commandParser.getHeader(), commandParser);
return true;
@@ -219,10 +222,12 @@ public CommandParser extends Command> unregisterCommandParser(String header) {
public boolean addAliasSymbol(AliasSymbol symbol) {
assert symbol != null;
- if (aliasingSymbols.containsKey(symbol.getKeyword()))
+ if (aliasingSymbols.containsKey(symbol.getKeyword())) {
return false;
- if (isCommandParserRegistered(symbol.getKeyword()))
+ }
+ if (isCommandParserRegistered(symbol.getKeyword())) {
return false;
+ }
aliasList.add(symbol);
aliasingSymbols.put(symbol.getKeyword(), symbol);
diff --git a/src/main/java/seedu/savvytasker/logic/parser/TaskFieldParser.java b/src/main/java/seedu/savvytasker/logic/parser/TaskFieldParser.java
index 361ad6944576..a15ace1d987a 100644
--- a/src/main/java/seedu/savvytasker/logic/parser/TaskFieldParser.java
+++ b/src/main/java/seedu/savvytasker/logic/parser/TaskFieldParser.java
@@ -9,7 +9,8 @@
/**
* This class contains common parsing methods for parsing Task fields.
* Each of the parse method takes in a string which can be null, and return
- * the respective parsed object.
+ * the respective parsed object. If null is provided to each of the parse methods,
+ * null will be returned.
*/
public abstract class TaskFieldParser implements CommandParser {
/*
@@ -32,8 +33,9 @@ protected TaskFieldParser() {
}
protected String parseTaskName(String taskNameText) throws ParseException {
- if (taskNameText == null)
+ if (taskNameText == null) {
return null;
+ }
return taskNameText.trim();
}
@@ -46,9 +48,9 @@ protected InferredDate parseEndDate(String dateText) throws ParseException {
}
private InferredDate parseDate(String dateText, String errorField) throws ParseException {
- if (dateText == null)
+ if (dateText == null) {
return null;
-
+ }
String trimmedDateText = dateText.trim();
try {
return dateParser.parseSingle(trimmedDateText);
@@ -58,14 +60,16 @@ private InferredDate parseDate(String dateText, String errorField) throws ParseE
}
protected String parseLocation(String locationText) throws ParseException {
- if (locationText == null)
+ if (locationText == null) {
return null;
+ }
return locationText.trim();
}
protected PriorityLevel parsePriorityLevel(String priorityLevelText) throws ParseException {
- if (priorityLevelText == null)
+ if (priorityLevelText == null) {
return null;
+ }
String trimmedPriorityLevelText = priorityLevelText.trim();
try {
@@ -76,8 +80,9 @@ protected PriorityLevel parsePriorityLevel(String priorityLevelText) throws Pars
}
protected RecurrenceType parseRecurrenceType(String recurrenceTypeText) throws ParseException {
- if (recurrenceTypeText == null)
+ if (recurrenceTypeText == null) {
return null;
+ }
String trimmedRecurrenceTypeText = recurrenceTypeText.trim();
try {
@@ -88,8 +93,9 @@ protected RecurrenceType parseRecurrenceType(String recurrenceTypeText) throws P
}
protected Integer parseNumberOfRecurrence(String numRecurrenceText) throws ParseException {
- if (numRecurrenceText == null)
+ if (numRecurrenceText == null) {
return null;
+ }
String trimmedNumRecurrenceText = numRecurrenceText.trim();
int numRecurrence = 0;
@@ -97,27 +103,48 @@ protected Integer parseNumberOfRecurrence(String numRecurrenceText) throws Parse
try {
numRecurrence = Integer.parseInt(trimmedNumRecurrenceText);
- if (numRecurrence < 0)
+ if (numRecurrence < 0) {
parseError = true;
+ }
} catch (NumberFormatException ex) {
parseError = true;
}
- if (parseError)
+ if (parseError) {
throw new ParseException(trimmedNumRecurrenceText, "NUMBER_OF_RECURRENCE: Must be a nonnegative whole number!");
+ }
return numRecurrence;
}
protected String parseCategory(String categoryText) throws ParseException {
- if (categoryText == null)
+ if (categoryText == null) {
return null;
+ }
return categoryText.trim();
}
protected String parseDescription(String descriptionText) throws ParseException {
- if (descriptionText == null)
+ if (descriptionText == null) {
return null;
+ }
return descriptionText.trim();
}
+ //@@author
+
+ //@@author A0138431L
+ public String parsefilePath(String filePathText) throws ParseException {
+ if (filePathText == null) {
+ return null;
+ }
+ return filePathText.trim();
+ }
+
+ public String parsefileName(String fileNameText) throws ParseException {
+ if (fileNameText == null) {
+ return null;
+ }
+ return fileNameText.trim();
+ }
+ //@@author
}
diff --git a/src/main/java/seedu/savvytasker/model/ListType.java b/src/main/java/seedu/savvytasker/model/ListType.java
index 2b7c9f244679..2e7fda37e229 100644
--- a/src/main/java/seedu/savvytasker/model/ListType.java
+++ b/src/main/java/seedu/savvytasker/model/ListType.java
@@ -32,8 +32,9 @@ public enum ListType {
*/
public static ListType valueOfIgnoreCase(String name) {
for (ListType type : ListType.values()) {
- if (type.toString().equalsIgnoreCase(name))
+ if (type.toString().equalsIgnoreCase(name)) {
return type;
+ }
}
throw new IllegalArgumentException("Unknown list type: " + name);
diff --git a/src/main/java/seedu/savvytasker/model/Model.java b/src/main/java/seedu/savvytasker/model/Model.java
index 4b081eb8ba34..bd52e32918b4 100644
--- a/src/main/java/seedu/savvytasker/model/Model.java
+++ b/src/main/java/seedu/savvytasker/model/Model.java
@@ -1,6 +1,7 @@
package seedu.savvytasker.model;
import java.util.LinkedList;
+import java.util.Date;
import seedu.savvytasker.commons.core.UnmodifiableObservableList;
import seedu.savvytasker.model.alias.AliasSymbol;
@@ -80,4 +81,33 @@ public interface Model {
/** Gets the number of aliases */
int getAliasSymbolCount();
+
+ //@@author A0138431L
+ /** Returns the filtered task list of overdue task as an {@code UnmodifiableObservableList}
+ * as of current date */
+ UnmodifiableObservableList getFilteredOverdueTasks();
+
+ /** Returns the filtered task list of floating task as an {@code UnmodifiableObservableList} */
+ UnmodifiableObservableList getFilteredFloatingTasks();
+
+ /** Returns the filtered task list of daily task as an {@code UnmodifiableObservableList}
+ * as of expected date */
+ UnmodifiableObservableList getFilteredDailyTasks(int dayOfWeek, Date date);
+
+ /** Returns the filtered task list of upcoming task as an {@code UnmodifiableObservableList}
+ * as of expected date */
+ UnmodifiableObservableList getFilteredUpcomingTasks(Date date);
+
+ /** Updates the filter of the filtered task list to show all overdue tasks */
+ void updateFilteredListToShowOverdue();
+
+ /** Updates the filter of the filtered task list to show all floating tasks */
+ void updateFilteredListToShowFloating();
+
+ /** Updates the filter of the filtered task list to show all tasks of the selected week*/
+ void updateFilteredListToShowDaily(int i);
+
+ /** Updates the filter of the filtered task list to show all upcoming tasks after the selected week*/
+ void updateFilteredListToShowUpcoming();
+ //@@author
}
diff --git a/src/main/java/seedu/savvytasker/model/ModelManager.java b/src/main/java/seedu/savvytasker/model/ModelManager.java
old mode 100644
new mode 100755
index 1551a6608316..396e49ed67ed
--- a/src/main/java/seedu/savvytasker/model/ModelManager.java
+++ b/src/main/java/seedu/savvytasker/model/ModelManager.java
@@ -1,7 +1,9 @@
package seedu.savvytasker.model;
import java.util.Arrays;
+import java.util.Calendar;
import java.util.Comparator;
+import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
@@ -9,6 +11,8 @@
import java.util.Set;
import java.util.logging.Logger;
+import org.apache.commons.lang.time.DateUtils;
+
import javafx.collections.transformation.FilteredList;
import javafx.collections.transformation.SortedList;
import seedu.savvytasker.commons.core.ComponentManager;
@@ -31,69 +35,141 @@
* All changes to any model should be synchronized.
*/
public class ModelManager extends ComponentManager implements Model {
- private static final Logger logger = LogsCenter.getLogger(ModelManager.class);
-
- //@@author A0139915W
- private final SavvyTasker savvyTasker;
- private final FilteredList filteredTasks;
- private final SortedList sortedAndFilteredTasks;
-
- /**
- * Initializes a ModelManager with the given SavvyTasker
- * and its variables should not be null
- */
- public ModelManager(SavvyTasker src) {
- super();
- assert src != null;
-
- logger.fine("Initializing with savvy tasker: " + src);
-
- savvyTasker = new SavvyTasker(src);
- filteredTasks = new FilteredList<>(savvyTasker.getTasks());
- sortedAndFilteredTasks = new SortedList<>(filteredTasks, new TaskSortedByDueDate());
- updateFilteredListToShowActive(); // shows only active tasks on start
- }
-
- public ModelManager() {
- this(new SavvyTasker());
- }
-
- public ModelManager(ReadOnlySavvyTasker initialData) {
- savvyTasker = new SavvyTasker(initialData);
- filteredTasks = new FilteredList<>(savvyTasker.getTasks());
- sortedAndFilteredTasks = new SortedList<>(filteredTasks, new TaskSortedByDueDate());
- updateFilteredListToShowActive(); // shows only active tasks on start
- }
- //@@author
-
- @Override
- public void resetData(ReadOnlySavvyTasker newData) {
- savvyTasker.resetData(newData);
- indicateSavvyTaskerChanged();
- }
-
- @Override
- public ReadOnlySavvyTasker getSavvyTasker() {
- return savvyTasker;
- }
-
- /** Raises an event to indicate the model has changed */
- private void indicateSavvyTaskerChanged() {
- raise(new SavvyTaskerChangedEvent(savvyTasker));
- }
- //@@author A0139916U
-
- private void indicateAliasSymbolAdded(AliasSymbol symbol) {
- raise(new AliasSymbolChangedEvent(symbol, AliasSymbolChangedEvent.Action.Added));
- }
-
- private void indicateAliasSymbolRemoved(AliasSymbol symbol) {
- raise(new AliasSymbolChangedEvent(symbol, AliasSymbolChangedEvent.Action.Removed));
- }
- //@@author
-
-
- //@@author A0139915W
+ private static final Logger logger = LogsCenter.getLogger(ModelManager.class);
+ Date onDate = new Date();
+ Date firstDayOfSelectedWeek = new Date();
+
+ //@@author A0138431L
+ private final SavvyTasker savvyTasker;
+ private final FilteredList filteredTasks;
+ private final SortedList sortedAndFilteredTasks;
+ private final FilteredList filteredFloatingTasks;
+ private final SortedList sortedAndFilteredFloatingTasks;
+ private final FilteredList filteredOverdueTasks;
+ private final SortedList sortedAndFilteredOverdueTasks;
+ private final FilteredList filteredDay1Tasks;
+ private final SortedList sortedAndFilteredDay1Tasks;
+ private final FilteredList filteredDay2Tasks;
+ private final SortedList sortedAndFilteredDay2Tasks;
+ private final FilteredList filteredDay3Tasks;
+ private final SortedList sortedAndFilteredDay3Tasks;
+ private final FilteredList filteredDay4Tasks;
+ private final SortedList sortedAndFilteredDay4Tasks;
+ private final FilteredList filteredDay5Tasks;
+ private final SortedList sortedAndFilteredDay5Tasks;
+ private final FilteredList filteredDay6Tasks;
+ private final SortedList sortedAndFilteredDay6Tasks;
+ private final FilteredList filteredDay7Tasks;
+ private final SortedList sortedAndFilteredDay7Tasks;
+ private final FilteredList filteredUpcomingTasks;
+ private final SortedList sortedAndFilteredUpcomingTasks;
+
+ /**
+ * Initializes a ModelManager with the given SavvyTasker
+ * and its variables should not be null
+ */
+ public ModelManager(SavvyTasker src) {
+ super();
+ assert src != null;
+
+ logger.fine("Initializing with savvy tasker: " + src);
+
+ savvyTasker = new SavvyTasker(src);
+ filteredTasks = new FilteredList<>(savvyTasker.getTasks());
+ sortedAndFilteredTasks = new SortedList<>(filteredTasks, new TaskSortedByDefault());
+
+ filteredFloatingTasks = new FilteredList<>(savvyTasker.getTasks());
+ sortedAndFilteredFloatingTasks = new SortedList<>(filteredFloatingTasks, new TaskSortedByDefault());
+
+ filteredOverdueTasks = new FilteredList<>(savvyTasker.getTasks());
+ sortedAndFilteredOverdueTasks = new SortedList<>(filteredOverdueTasks, new TaskSortedByDefault());
+
+ filteredDay1Tasks = new FilteredList<>(savvyTasker.getTasks());
+ sortedAndFilteredDay1Tasks = new SortedList<>(filteredDay1Tasks, new TaskSortedByDefault());
+ filteredDay2Tasks = new FilteredList<>(savvyTasker.getTasks());
+ sortedAndFilteredDay2Tasks = new SortedList<>(filteredDay2Tasks, new TaskSortedByDefault());
+ filteredDay3Tasks = new FilteredList<>(savvyTasker.getTasks());
+ sortedAndFilteredDay3Tasks = new SortedList<>(filteredDay3Tasks, new TaskSortedByDefault());
+ filteredDay4Tasks = new FilteredList<>(savvyTasker.getTasks());
+ sortedAndFilteredDay4Tasks = new SortedList<>(filteredDay4Tasks, new TaskSortedByDefault());
+ filteredDay5Tasks = new FilteredList<>(savvyTasker.getTasks());
+ sortedAndFilteredDay5Tasks = new SortedList<>(filteredDay5Tasks, new TaskSortedByDefault());
+ filteredDay6Tasks = new FilteredList<>(savvyTasker.getTasks());
+ sortedAndFilteredDay6Tasks = new SortedList<>(filteredDay6Tasks, new TaskSortedByDefault());
+ filteredDay7Tasks = new FilteredList<>(savvyTasker.getTasks());
+ sortedAndFilteredDay7Tasks = new SortedList<>(filteredDay7Tasks, new TaskSortedByDefault());
+
+ filteredUpcomingTasks = new FilteredList<>(savvyTasker.getTasks());
+ sortedAndFilteredUpcomingTasks = new SortedList<>(filteredUpcomingTasks, new TaskSortedByDefault());
+
+ updateFilteredListToShowActive(); // shows only active tasks on start
+ }
+
+ public ModelManager() {
+ this(new SavvyTasker());
+ }
+
+ public ModelManager(ReadOnlySavvyTasker initialData) {
+ savvyTasker = new SavvyTasker(initialData);
+ filteredTasks = new FilteredList<>(savvyTasker.getTasks());
+ sortedAndFilteredTasks = new SortedList<>(filteredTasks, new TaskSortedByDefault());
+
+ filteredFloatingTasks = new FilteredList<>(savvyTasker.getTasks());
+ sortedAndFilteredFloatingTasks = new SortedList<>(filteredFloatingTasks, new TaskSortedByDefault());
+
+ filteredOverdueTasks = new FilteredList<>(savvyTasker.getTasks());
+ sortedAndFilteredOverdueTasks = new SortedList<>(filteredOverdueTasks, new TaskSortedByDefault());
+
+ filteredDay1Tasks = new FilteredList<>(savvyTasker.getTasks());
+ sortedAndFilteredDay1Tasks = new SortedList<>(filteredDay1Tasks, new TaskSortedByDefault());
+ filteredDay2Tasks = new FilteredList<>(savvyTasker.getTasks());
+ sortedAndFilteredDay2Tasks = new SortedList<>(filteredDay2Tasks, new TaskSortedByDefault());
+ filteredDay3Tasks = new FilteredList<>(savvyTasker.getTasks());
+ sortedAndFilteredDay3Tasks = new SortedList<>(filteredDay3Tasks, new TaskSortedByDefault());
+ filteredDay4Tasks = new FilteredList<>(savvyTasker.getTasks());
+ sortedAndFilteredDay4Tasks = new SortedList<>(filteredDay4Tasks, new TaskSortedByDefault());
+ filteredDay5Tasks = new FilteredList<>(savvyTasker.getTasks());
+ sortedAndFilteredDay5Tasks = new SortedList<>(filteredDay5Tasks, new TaskSortedByDefault());
+ filteredDay6Tasks = new FilteredList<>(savvyTasker.getTasks());
+ sortedAndFilteredDay6Tasks = new SortedList<>(filteredDay6Tasks, new TaskSortedByDefault());
+ filteredDay7Tasks = new FilteredList<>(savvyTasker.getTasks());
+ sortedAndFilteredDay7Tasks = new SortedList<>(filteredDay7Tasks, new TaskSortedByDefault());
+
+ filteredUpcomingTasks = new FilteredList<>(savvyTasker.getTasks());
+ sortedAndFilteredUpcomingTasks = new SortedList<>(filteredUpcomingTasks, new TaskSortedByDefault());
+
+ updateFilteredListToShowActive(); // shows only active tasks on start
+ }
+ //@@author
+
+ @Override
+ public void resetData(ReadOnlySavvyTasker newData) {
+ savvyTasker.resetData(newData);
+ indicateSavvyTaskerChanged();
+ }
+
+ @Override
+ public ReadOnlySavvyTasker getSavvyTasker() {
+ return savvyTasker;
+ }
+
+ /** Raises an event to indicate the model has changed */
+ private void indicateSavvyTaskerChanged() {
+ raise(new SavvyTaskerChangedEvent(savvyTasker));
+ }
+ //@@author A0139916U
+
+ private void indicateAliasSymbolAdded(AliasSymbol symbol) {
+ raise(new AliasSymbolChangedEvent(symbol, AliasSymbolChangedEvent.Action.Added));
+ }
+
+ private void indicateAliasSymbolRemoved(AliasSymbol symbol) {
+ raise(new AliasSymbolChangedEvent(symbol, AliasSymbolChangedEvent.Action.Removed));
+ }
+ //@@author
+
+
+ //@@author A0139915W
@Override
public synchronized Task deleteTask(ReadOnlyTask target) throws TaskNotFoundException {
Task taskDeleted = savvyTasker.removeTask(target);
@@ -124,8 +200,8 @@ public synchronized LinkedList addRecurringTask(Task recurringTask) throws
return recurringTasks;
}
//@@author
-
- //@@author A0139916U
+
+ //@@author A0139916U
@Override
public synchronized void addAliasSymbol(AliasSymbol symbol) throws DuplicateSymbolKeywordException {
savvyTasker.addAliasSymbol(symbol);
@@ -146,7 +222,7 @@ public int getAliasSymbolCount() {
}
//@@author
- //=========== Filtered/Sorted Task List Accessors ===============================================================
+ //=========== Filtered/Sorted Task List Accessors ===============================================================
//@@author A0139915W
@Override
@@ -168,52 +244,183 @@ public void updateFilteredListToShowActiveSortedByPriorityLevel() {
public void updateFilteredListToShowActive() {
updateFilteredTaskList(new PredicateExpression(new TaskIsActiveQualifier()));
}
- private void updateFilteredListToShowActive(Comparator comparator) {
- updateFilteredTaskList(
- new PredicateExpression(new TaskIsActiveQualifier()),
- comparator);
- }
-
- @Override
- public void updateFilteredListToShowArchived() {
- updateFilteredTaskList(new PredicateExpression(new TaskIsArchivedQualifier()));
- }
-
- @Override
- public void updateFilteredTaskList(FindType findType, String[] keywords) {
- assert findType != null;
- Qualifier qualifier = null;
- switch (findType)
- {
- case Partial:
- qualifier = new TaskNamePartialMatchQualifier(keywords);
- break;
- case Full:
- qualifier = new TaskNameFullMatchQualifier(keywords);
- break;
- case Exact:
- qualifier = new TaskNameExactMatchQualifier(keywords);
- break;
- case Category:
- qualifier = new CategoryPartialMatchQualifier(keywords);
- break;
- default:
- assert false; // should never get here.
- }
- updateFilteredTaskList(new PredicateExpression(qualifier));
- }
- private void updateFilteredTaskList(Expression expression) {
- updateFilteredTaskList(expression, new TaskSortedByDefault());
- }
-
- private void updateFilteredTaskList(Expression expression, Comparator comparator) {
- filteredTasks.setPredicate(expression::satisfies);
- sortedAndFilteredTasks.setComparator(comparator);
- }
- //@@author
-
- //========== Inner classes/interfaces used for filtering ==================================================
+ private void updateFilteredListToShowActive(Comparator comparator) {
+ updateFilteredTaskList(
+ new PredicateExpression(new TaskIsActiveQualifier()),
+ comparator);
+ }
+
+ @Override
+ public void updateFilteredListToShowArchived() {
+ updateFilteredTaskList(new PredicateExpression(new TaskIsArchivedQualifier()));
+ }
+
+ @Override
+ public void updateFilteredTaskList(FindType findType, String[] keywords) {
+ assert findType != null;
+ Qualifier qualifier = null;
+ switch (findType)
+ {
+ case Partial:
+ qualifier = new TaskNamePartialMatchQualifier(keywords);
+ break;
+ case Full:
+ qualifier = new TaskNameFullMatchQualifier(keywords);
+ break;
+ case Exact:
+ qualifier = new TaskNameExactMatchQualifier(keywords);
+ break;
+ case Category:
+ qualifier = new CategoryPartialMatchQualifier(keywords);
+ break;
+ default:
+ assert false; // should never get here.
+ break;
+ }
+ updateFilteredTaskList(new PredicateExpression(qualifier));
+ }
+
+ private void updateFilteredTaskList(Expression expression) {
+ updateFilteredTaskList(expression, new TaskSortedByDefault());
+ }
+
+ private void updateFilteredTaskList(Expression expression, Comparator comparator) {
+ filteredTasks.setPredicate(expression::satisfies);
+ sortedAndFilteredTasks.setComparator(comparator);
+ }
+ //@@author
+
+ //@author A0138431L
+ //Get filtered task list according to date category
+ @Override
+ public UnmodifiableObservableList getFilteredOverdueTasks() {
+ updateFilteredListToShowOverdue();
+ return new UnmodifiableObservableList(filteredOverdueTasks);
+ }
+
+ @Override
+ public UnmodifiableObservableList getFilteredFloatingTasks() {
+ updateFilteredListToShowFloating();
+ return new UnmodifiableObservableList(filteredFloatingTasks);
+ }
+
+ @Override
+ public UnmodifiableObservableList getFilteredDailyTasks(int dayOfWeek, Date date) {
+ this.onDate = date;
+ updateFilteredListToShowDaily(dayOfWeek);
+ switch(dayOfWeek) {
+ case 0:
+ return new UnmodifiableObservableList(filteredDay1Tasks);
+ case 1:
+ return new UnmodifiableObservableList(filteredDay2Tasks);
+ case 2:
+ return new UnmodifiableObservableList(filteredDay3Tasks);
+ case 3:
+ return new UnmodifiableObservableList(filteredDay4Tasks);
+ case 4:
+ return new UnmodifiableObservableList(filteredDay5Tasks);
+ case 5:
+ return new UnmodifiableObservableList(filteredDay6Tasks);
+ case 6:
+ return new UnmodifiableObservableList(filteredDay7Tasks);
+ default:
+ return new UnmodifiableObservableList(filteredDay1Tasks);
+ }
+ }
+
+ @Override
+ public UnmodifiableObservableList getFilteredUpcomingTasks(Date date) {
+ this.firstDayOfSelectedWeek = date;
+ updateFilteredListToShowUpcoming();
+ return new UnmodifiableObservableList(filteredUpcomingTasks);
+ }
+
+ //Binding isOverdue quantifier predicate to filtered list
+ @Override
+ public void updateFilteredListToShowOverdue() {
+ updateFilteredOverdueTaskList(new PredicateExpression(new TaskIsOverdueQualifier()));
+ }
+
+ private void updateFilteredOverdueTaskList(Expression expression) {
+ updateFilteredOverdueTaskList(expression, new TaskSortedByDefault());
+ }
+
+ private void updateFilteredOverdueTaskList(Expression expression, Comparator comparator) {
+ filteredOverdueTasks.setPredicate(expression::satisfies);
+ sortedAndFilteredOverdueTasks.setComparator(comparator);
+ }
+
+ //Binding isFloating quantifier predicate to filtered list
+ @Override
+ public void updateFilteredListToShowFloating() {
+ updateFilteredFloatingTaskList(new PredicateExpression(new TaskIsFloatingQualifier()));
+ }
+
+ private void updateFilteredFloatingTaskList(Expression expression) {
+ updateFilteredFloatingTaskList(expression, new TaskSortedByDefault());
+ }
+
+ private void updateFilteredFloatingTaskList(Expression expression, Comparator comparator) {
+ filteredFloatingTasks.setPredicate(expression::satisfies);
+ sortedAndFilteredFloatingTasks.setComparator(comparator);
+ }
+
+ //Binding isOnDate quantifier predicate to filtered list
+ @Override
+ public void updateFilteredListToShowDaily(int dayOfWeek) {
+ updateFilteredDailyTaskList(new PredicateExpression(new TaskIsOnDateQualifier()), dayOfWeek);
+ }
+
+ private void updateFilteredDailyTaskList(Expression expression, int dayOfWeek) {
+ updateFilteredDailyTaskList(expression, new TaskSortedByDefault(), dayOfWeek);
+ }
+
+ private void updateFilteredDailyTaskList(Expression expression, Comparator comparator, int dayOfWeek) {
+ switch(dayOfWeek) {
+ case 0:
+ filteredDay1Tasks.setPredicate(expression::satisfies);
+ sortedAndFilteredDay1Tasks.setComparator(comparator);
+ case 1:
+ filteredDay2Tasks.setPredicate(expression::satisfies);
+ sortedAndFilteredDay2Tasks.setComparator(comparator);
+ case 2:
+ filteredDay3Tasks.setPredicate(expression::satisfies);
+ sortedAndFilteredDay3Tasks.setComparator(comparator);
+ case 3:
+ filteredDay4Tasks.setPredicate(expression::satisfies);
+ sortedAndFilteredDay4Tasks.setComparator(comparator);
+ case 4:
+ filteredDay5Tasks.setPredicate(expression::satisfies);
+ sortedAndFilteredDay5Tasks.setComparator(comparator);
+ case 5:
+ filteredDay6Tasks.setPredicate(expression::satisfies);
+ sortedAndFilteredDay6Tasks.setComparator(comparator);
+ case 6:
+ filteredDay7Tasks.setPredicate(expression::satisfies);
+ sortedAndFilteredDay7Tasks.setComparator(comparator);
+
+ }
+ }
+
+ //Binding isUpcoming quantifier predicate to filtered list
+ @Override
+ public void updateFilteredListToShowUpcoming() {
+ updateFilteredUpcomingTaskList(new PredicateExpression(new TaskIsUpcomingQualifier()));
+ }
+
+ private void updateFilteredUpcomingTaskList(Expression expression) {
+ updateFilteredUpcomingTaskList(expression, new TaskSortedByDefault());
+ }
+
+ private void updateFilteredUpcomingTaskList(Expression expression, Comparator comparator) {
+ filteredUpcomingTasks.setPredicate(expression::satisfies);
+ sortedAndFilteredUpcomingTasks.setComparator(comparator);
+ }
+
+ //@@author
+
+ //========== Inner classes/interfaces used for filtering ==================================================
interface Expression {
boolean satisfies(ReadOnlyTask task);
@@ -259,7 +466,6 @@ default Set createSet(String[] keywords) {
//@@author A0139915W
/**
* Qualifier matching a partial word from the set of keywords
- * @author A0139915W
*/
private class CategoryPartialMatchQualifier implements Qualifier {
private Set keyWordsToMatch;
@@ -284,7 +490,6 @@ public String toString() {
/**
* Qualifier matching a partial word from the set of keywords
- * @author A0139915W
*/
private class TaskNamePartialMatchQualifier implements Qualifier {
private Set keyWordsToMatch;
@@ -309,7 +514,6 @@ public String toString() {
/**
* Qualifier matching a full word from the set of keywords
- * @author A0139915W
*/
private class TaskNameFullMatchQualifier implements Qualifier {
private Set keyWordsToMatch;
@@ -334,7 +538,6 @@ public String toString() {
/**
* Qualifier matching a exactly from the set of keywords
- * @author A0139915W
*/
private class TaskNameExactMatchQualifier implements Qualifier {
private Set keyWordsToMatch;
@@ -378,14 +581,13 @@ public String toString() {
/**
* Qualifier for checking if {@link Task} is active. Tasks that are not archived are active.
- * @author A0139915W
*
*/
private class TaskIsActiveQualifier implements Qualifier {
@Override
public boolean run(ReadOnlyTask task) {
- return task.isArchived() == false;
+ return !task.isArchived();
}
@Override
@@ -396,54 +598,268 @@ public String toString() {
/**
* Qualifier for checking if {@link Task} is archived
- * @author A0139915W
*
*/
private class TaskIsArchivedQualifier implements Qualifier {
@Override
public boolean run(ReadOnlyTask task) {
- return task.isArchived() == true;
+ return task.isArchived();
}
@Override
public String toString() {
return "isArchived=true";
}
- }
+ }//@@author
+
+ //@@author A0138431L
+ /**
+ * Qualifier for checking if {@link Task} is an overdue task
+ *
+ * A overdue task is a deadline or event task with end dateTime after current dateTime
+ *
+ * @return true if the task is overdue
+ *
+ */
+ private class TaskIsOverdueQualifier implements Qualifier {
+
+ @Override
+ public boolean run(ReadOnlyTask task) {
+
+ Date today = new Date();
+
+ boolean isOverdue = false;
+
+ if (task.getEndDateTime() != null) {
+
+ Date endDateTime = task.getEndDateTime();
+
+ if (endDateTime.compareTo(today)<0 && task.isArchived() == false) {
+
+ isOverdue = true;
+ }
+
+ }
+
+ return isOverdue;
+
+ }
+
+ @Override
+ public String toString() {
+ return "isOverdue=true";
+ }
+ }
+
+ /**
+ * Qualifier for checking if {@link Task} is a floating task
+ *
+ * A floating task do not have start or end time
+ *
+ * @return true if the task falls on the date specified. else return false
+ *
+ */
+ private class TaskIsFloatingQualifier implements Qualifier {
+
+ @Override
+ public boolean run(ReadOnlyTask task) {
+
+ boolean isFloating = false;
+
+ if(task.getStartDateTime() == null && task.getEndDateTime() == null && task.isArchived() == false) {
+
+ isFloating = true;
+
+ }
+
+ return isFloating;
+
+ }
+
+ @Override
+ public String toString() {
+ return "isFloating=true";
+ }
+ }
+
+ /**
+ * Qualifier for checking if {@link Task} falls on the selected date
+ *
+ * Check whether the task is on the date specified (for deadline tasks)
+ * Check whether the date specified is within the range of date the task (for event tasks)
+ * Includes task that are completed.
+ *
+ * @return true if the task falls on the date specified. else return false
+ *
+ */
+ private class TaskIsOnDateQualifier implements Qualifier {
+
+ @Override
+ public boolean run(ReadOnlyTask task) {
+
+ Date expectedDate = onDate;
+
+ boolean isOnDate = false;
+
+ //Archived Task
+ if(task.isArchived() == true){
+
+ isOnDate = false;
+
+ }
+ //Deadline Task
+ else if(task.getStartDateTime() == null && task.getEndDateTime() != null) {
+
+ Date endDateTime = task.getEndDateTime();
+
+ if (DateUtils.isSameDay(endDateTime, expectedDate)) {
+
+ isOnDate = true;
+
+ }
+
+ }
+ //Event Task
+ else if(task.getStartDateTime() != null && task.getEndDateTime() != null) {
+
+ Date startDateTime = task.getStartDateTime();
+ Date endDateTime = task.getEndDateTime();
+
+ if (DateUtils.isSameDay(startDateTime, expectedDate)) {
+
+ isOnDate = true;
+
+ } else if (DateUtils.isSameDay(endDateTime, expectedDate)) {
+
+ isOnDate = true;
+
+ } else if (startDateTime.compareTo(expectedDate)<0 && expectedDate.compareTo(endDateTime)<0) {
+
+ isOnDate = true;
+
+ }
+ }
+
+ return isOnDate;
+ }
+
+ @Override
+ public String toString() {
+ return "isOnDate=true";
+ }
+ }
+
+ /**
+ * Qualifier for checking if {@link Task} task is upcoming
+ *
+ * A upcoming task is a task that will happen after the last day, 2359 of selected week
+ *
+ * @return true if the task is a upcoming task
+ *
+ */
+ private class TaskIsUpcomingQualifier implements Qualifier {
+
+ @Override
+ public boolean run(ReadOnlyTask task) {
+
+ Date lastDateOfExpectedWeek = firstDayOfSelectedWeek;
+
+ //convert date object to calendar object and add 7 days, last day of the selected week
+ Calendar calendarExpectedDate = Calendar.getInstance();
+ calendarExpectedDate.setTime(lastDateOfExpectedWeek);
+ calendarExpectedDate.add(Calendar.DAY_OF_MONTH, 7);
+ calendarExpectedDate.set(Calendar.HOUR_OF_DAY,23);
+ calendarExpectedDate.set(Calendar.MINUTE,59);
+ calendarExpectedDate.set(Calendar.SECOND,59);
+
+ //convert calendar object back to date object
+ lastDateOfExpectedWeek = calendarExpectedDate.getTime();
+
+ boolean isUpcoming = true;
+
+ //Archived Task
+ if(task.isArchived() == true){
+
+ isUpcoming = false;
+
+ }
+
+ //Floating Task
+ else if(task.getStartDateTime() == null && task.getEndDateTime() == null) {
+
+ isUpcoming = false;
+
+ }
+ //Deadline Task
+ else if(task.getStartDateTime() == null && task.getEndDateTime() != null) {
+
+
+ if (task.getEndDateTime().compareTo(lastDateOfExpectedWeek)<0) {
+
+ isUpcoming = false;
+
+ }
+
+ }
+ //Event Task
+ else {
+
+ if (task.getStartDateTime().compareTo(lastDateOfExpectedWeek)<0) {
+
+ isUpcoming = false;
+
+ }
+
+ }
+
+ return isUpcoming;
+ }
+
+ @Override
+ public String toString() {
+ return "isUpcoming=true";
+ }
+ }//@@author
- //========== Inner classes/interfaces used for sorting ==================================================
+ //@@author A0139915W
+
+ //========== Inner classes/interfaces used for sorting ==================================================
/**
* Compares {@link Task} by their default field, id
- * @author A0139915W
- *
*/
private class TaskSortedByDefault implements Comparator {
@Override
public int compare(Task task1, Task task2) {
- if (task1 == null && task2 == null) return 0;
- else if (task1 == null) return 1;
- else if (task2 == null) return -1;
- else return task1.getId() - task2.getId();
+ if (task1 == null && task2 == null) {
+ return 0;
+ } else if (task1 == null) {
+ return 1;
+ } else if (task2 == null) {
+ return -1;
+ } else {
+ return task1.getId() - task2.getId();
+ }
}
}
/**
* Compares {@link Task} by their DueDate
- * @author A0139915W
- *
*/
private class TaskSortedByDueDate implements Comparator {
@Override
public int compare(Task task1, Task task2) {
- if (task1 == null && task2 == null) return 0;
- else if (task1 == null) return 1;
- else if (task2 == null) return -1;
- else {
+ if (task1 == null && task2 == null) {
+ return 0;
+ } else if (task1 == null) {
+ return 1;
+ } else if (task2 == null) {
+ return -1;
+ } else {
// End dates can be nulls (floating tasks)
// Check for existence of endDateTime before comparing
if (task1.getEndDateTime() == null &&
@@ -463,8 +879,6 @@ public int compare(Task task1, Task task2) {
/**
* Compares {@link Task} by their PriorityLevel
- * @author A0139915W
- *
*/
private class TaskSortedByPriorityLevel implements Comparator {
@@ -481,4 +895,4 @@ public int compare(Task task1, Task task2) {
}
//@@author
-}
+}
\ No newline at end of file
diff --git a/src/main/java/seedu/savvytasker/model/SavvyTasker.java b/src/main/java/seedu/savvytasker/model/SavvyTasker.java
index 7b32afb8635f..f85f4307df2d 100644
--- a/src/main/java/seedu/savvytasker/model/SavvyTasker.java
+++ b/src/main/java/seedu/savvytasker/model/SavvyTasker.java
@@ -202,8 +202,10 @@ private Task setDatesForRecurringType(Task t, RecurrenceType recurringType, int
}
break;
case None:
+ //fall through
default:
assert false; // should not come here
+ break;
}
t.setStartDateTime(startDate);
t.setEndDateTime(endDate);
diff --git a/src/main/java/seedu/savvytasker/model/task/FindType.java b/src/main/java/seedu/savvytasker/model/task/FindType.java
index 49e69023a5f8..aab2e4e9b111 100644
--- a/src/main/java/seedu/savvytasker/model/task/FindType.java
+++ b/src/main/java/seedu/savvytasker/model/task/FindType.java
@@ -38,8 +38,9 @@ public enum FindType {
*/
public static FindType valueOfIgnoreCase(String name) {
for (FindType type : FindType.values()) {
- if (type.toString().equalsIgnoreCase(name))
+ if (type.toString().equalsIgnoreCase(name)) {
return type;
+ }
}
throw new IllegalArgumentException("Unknown find type: " + name);
diff --git a/src/main/java/seedu/savvytasker/model/task/PriorityLevel.java b/src/main/java/seedu/savvytasker/model/task/PriorityLevel.java
index 16db6b967ea6..836b8faeedfb 100644
--- a/src/main/java/seedu/savvytasker/model/task/PriorityLevel.java
+++ b/src/main/java/seedu/savvytasker/model/task/PriorityLevel.java
@@ -16,8 +16,9 @@ public enum PriorityLevel {
*/
public static PriorityLevel valueOfIgnoreCase(String name) {
for (PriorityLevel type : PriorityLevel.values()) {
- if (type.toString().equalsIgnoreCase(name))
+ if (type.toString().equalsIgnoreCase(name)) {
return type;
+ }
}
throw new IllegalArgumentException("Unknown priority level: " + name);
diff --git a/src/main/java/seedu/savvytasker/model/task/ReadOnlyTask.java b/src/main/java/seedu/savvytasker/model/task/ReadOnlyTask.java
index 9b4df673008c..a8648b5cfe9f 100644
--- a/src/main/java/seedu/savvytasker/model/task/ReadOnlyTask.java
+++ b/src/main/java/seedu/savvytasker/model/task/ReadOnlyTask.java
@@ -61,8 +61,10 @@ default String getAsText() {
}
if (getDescription() != null && !getDescription().isEmpty()) {
builder.append(" Description: ")
- . append(getDescription());
+ .append(getDescription());
}
+ builder.append(" Archived: ")
+ .append(isArchived());
return builder.toString();
}
@@ -100,8 +102,6 @@ default String getTextForUi() {
.append(getDescription())
.append("\n");
}
- builder.append(" Archived: ")
- .append(isArchived());
return builder.toString();
}
diff --git a/src/main/java/seedu/savvytasker/model/task/RecurrenceType.java b/src/main/java/seedu/savvytasker/model/task/RecurrenceType.java
index 4d3fa8f4aca3..cb4e32e59f16 100644
--- a/src/main/java/seedu/savvytasker/model/task/RecurrenceType.java
+++ b/src/main/java/seedu/savvytasker/model/task/RecurrenceType.java
@@ -33,8 +33,9 @@ public enum RecurrenceType {
*/
public static RecurrenceType valueOfIgnoreCase(String name) {
for (RecurrenceType type : RecurrenceType.values()) {
- if (type.toString().equalsIgnoreCase(name))
+ if (type.toString().equalsIgnoreCase(name)) {
return type;
+ }
}
throw new IllegalArgumentException("Unknown recurrence type: " + name);
diff --git a/src/main/java/seedu/savvytasker/model/task/Task.java b/src/main/java/seedu/savvytasker/model/task/Task.java
index 593822c9bf31..361060f26140 100644
--- a/src/main/java/seedu/savvytasker/model/task/Task.java
+++ b/src/main/java/seedu/savvytasker/model/task/Task.java
@@ -134,10 +134,7 @@ public Task(ReadOnlyTask source, String taskName, InferredDate startDateTime, In
}
private void setStartDate(InferredDate inferredDate) {
- if (inferredDate == null) {
- // user didn't specify s/
- // keep existing start date
- } else {
+ if (inferredDate != null) {
if (inferredDate.isDateInferred() && inferredDate.isTimeInferred()) {
// user specified s/ but with nothing tagged to it
// remove existing start date
@@ -152,10 +149,7 @@ private void setStartDate(InferredDate inferredDate) {
}
private void setEndDate(InferredDate inferredDate) {
- if (inferredDate == null) {
- // user didn't specify e/
- // keep existing end date
- } else {
+ if (inferredDate != null) {
if (inferredDate.isDateInferred() && inferredDate.isTimeInferred()) {
// user specified e/ but with nothing tagged to it
// remove existing end date
@@ -279,8 +273,11 @@ public void setDescription(String description) {
}
public void setArchived(boolean isArchived) {
- if (isArchived) mark();
- else unmark();
+ if (isArchived) {
+ mark();
+ } else {
+ unmark();
+ }
}
/**
diff --git a/src/main/java/seedu/savvytasker/model/task/TaskList.java b/src/main/java/seedu/savvytasker/model/task/TaskList.java
index 6c68eab70ae7..2165115f7c17 100644
--- a/src/main/java/seedu/savvytasker/model/task/TaskList.java
+++ b/src/main/java/seedu/savvytasker/model/task/TaskList.java
@@ -17,6 +17,12 @@
*/
public class TaskList implements Iterable {
+ private final ObservableList internalList = FXCollections.observableArrayList();
+ private int nextId = 0;
+ private boolean isNextIdInitialized = false;
+ private int nextGroupId = 0;
+ private boolean isNextGroupIdInitialized = false;
+
/**
* Signals that an operation would have violated the 'end time earlier than start time' property of the list.
*/
@@ -58,17 +64,6 @@ public static class TaskNotFoundException extends Exception {
*/
private static final long serialVersionUID = -7591982407764643511L;
}
-
- private final ObservableList internalList = FXCollections.observableArrayList();
- private int nextId = 0;
- private boolean isNextIdInitialized = false;
- private int nextGroupId = 0;
- private boolean isNextGroupIdInitialized = false;
-
- /**
- * Constructs empty TaskList.
- */
- public TaskList() {}
/**
* Gets the next available id for uniquely identifying a task in
@@ -129,11 +124,8 @@ public boolean contains(ReadOnlyTask toCheck) {
*/
public boolean isValidStartEnd(ReadOnlyTask toCheck) {
assert toCheck != null;
- if (toCheck.getStartDateTime() != null && toCheck.getEndDateTime() != null &&
- toCheck.getStartDateTime().compareTo(toCheck.getEndDateTime()) >= 0) {
- return false;
- }
- return true;
+ return toCheck.getStartDateTime() == null || toCheck.getEndDateTime() == null ||
+ toCheck.getStartDateTime().compareTo(toCheck.getEndDateTime()) < 0;
}
/**
diff --git a/src/main/java/seedu/savvytasker/storage/ConfigStorage.java b/src/main/java/seedu/savvytasker/storage/ConfigStorage.java
new file mode 100644
index 000000000000..72ac5051173e
--- /dev/null
+++ b/src/main/java/seedu/savvytasker/storage/ConfigStorage.java
@@ -0,0 +1,29 @@
+//@@author A0138431L
+package seedu.savvytasker.storage;
+
+import java.io.IOException;
+import java.util.Optional;
+
+import seedu.savvytasker.commons.core.Config;
+import seedu.savvytasker.commons.exceptions.DataConversionException;
+
+/**
+ * Represents a storage for {@link seedu.savvytasker.commons.core.Config}.
+ */
+public interface ConfigStorage {
+ /**
+ * Returns Config data from storage.
+ * Returns {@code Optional.empty()} if storage file is not found.
+ * @throws DataConversionException if the data in storage is not in the expected format.
+ * @throws IOException if there was any problem when reading from the storage.
+ */
+ Optional readConfigFile() throws DataConversionException, IOException;
+
+ /**
+ * Saves the given {@link seedu.savvytasker.commons.core.Config} to the storage.
+ * @param config cannot be null.
+ * @throws IOException if there was any problem writing to the file.
+ */
+ void saveConfigFile(Config config) throws IOException;
+
+}
\ No newline at end of file
diff --git a/src/main/java/seedu/savvytasker/storage/JsonConfigStorage.java b/src/main/java/seedu/savvytasker/storage/JsonConfigStorage.java
new file mode 100644
index 000000000000..271de40c6e9b
--- /dev/null
+++ b/src/main/java/seedu/savvytasker/storage/JsonConfigStorage.java
@@ -0,0 +1,90 @@
+//@@author A0138431L
+
+package seedu.savvytasker.storage;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Optional;
+import java.util.logging.Logger;
+
+import seedu.savvytasker.commons.core.Config;
+import seedu.savvytasker.commons.core.LogsCenter;
+import seedu.savvytasker.commons.exceptions.DataConversionException;
+import seedu.savvytasker.commons.util.FileUtil;
+
+/**
+ * A class to access Config stored in the hard disk as a json file
+ */
+public class JsonConfigStorage implements ConfigStorage {
+
+ private static final Logger logger = LogsCenter.getLogger(JsonConfigStorage.class);
+
+ private String filePath;
+
+ public JsonConfigStorage(String filePath) {
+
+ this.filePath = filePath;
+ }
+
+ @Override
+ public Optional readConfigFile() throws DataConversionException, IOException {
+
+ return readConfig(filePath);
+ }
+
+ @Override
+ public void saveConfigFile(Config config) throws IOException {
+
+ saveConfig(config, filePath);
+ }
+
+ /**
+ * Similar to {@link #readConfigFile()}
+ * @param configFilePath location of the data. Cannot be null.
+ * @throws DataConversionException if the file format is not as expected.
+ */
+ public Optional readConfig(String configFilePath) throws DataConversionException {
+
+ assert configFilePath != null;
+
+ File configFile = new File(configFilePath);
+
+ if (!configFile.exists()) {
+
+ logger.info("Config file " + configFile + " not found");
+
+ return Optional.empty();
+
+ }
+
+ Config config;
+
+ try {
+
+ config = FileUtil.deserializeObjectFromJsonFile(configFile, Config.class);
+
+ } catch (IOException e) {
+
+ logger.warning("Error reading from config file " + configFile + ": " + e);
+
+ throw new DataConversionException(e);
+
+ }
+
+ return Optional.of(config);
+ }
+
+ /**
+ * Similar to {@link #saveConfigFile(Config)}
+ * @param configFilePath location of the data. Cannot be null.
+ */
+ private void saveConfig(Config config, String configFilePath) throws IOException {
+
+ assert config != null;
+ assert configFilePath != null;
+ assert !configFilePath.isEmpty();
+
+ FileUtil.serializeObjectToJsonFile(new File(configFilePath), config);
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/seedu/savvytasker/storage/StorageManager.java b/src/main/java/seedu/savvytasker/storage/StorageManager.java
index a9d463a690b4..5510e67eaef1 100644
--- a/src/main/java/seedu/savvytasker/storage/StorageManager.java
+++ b/src/main/java/seedu/savvytasker/storage/StorageManager.java
@@ -84,7 +84,7 @@ public void saveSavvyTasker(ReadOnlySavvyTasker savvyTasker, String filePath) th
savvyTaskerStorage.saveSavvyTasker(savvyTasker, filePath);
}
- //@@author A0139915W
+ //@@author A0138431L
@Override
@Subscribe
public void handleSavvyTaskerSaveLocationChangedEvent(DataSavingLocationChangedEvent dslce) {
diff --git a/src/main/java/seedu/savvytasker/storage/XmlSerializableSavvyTasker.java b/src/main/java/seedu/savvytasker/storage/XmlSerializableSavvyTasker.java
index da4e0a98cc93..0c9e71e69558 100644
--- a/src/main/java/seedu/savvytasker/storage/XmlSerializableSavvyTasker.java
+++ b/src/main/java/seedu/savvytasker/storage/XmlSerializableSavvyTasker.java
@@ -28,20 +28,19 @@ public class XmlSerializableSavvyTasker implements ReadOnlySavvyTasker {
@XmlElement
private List symbols;
- {
- tasks = new ArrayList<>();
- symbols = new ArrayList<>();
- }
-
/**
* Empty constructor required for marshalling
*/
- public XmlSerializableSavvyTasker() {}
+ public XmlSerializableSavvyTasker() {
+ tasks = new ArrayList<>();
+ symbols = new ArrayList<>();
+ }
/**
* Conversion
*/
public XmlSerializableSavvyTasker(ReadOnlySavvyTasker src) {
+ this();
tasks.addAll(src.getReadOnlyListOfTasks().stream().map(XmlAdaptedTask::new).collect(Collectors.toList()));
symbols.addAll(src.getReadOnlyListOfAliasSymbols().stream().map(XmlAdaptedAliasSymbol::new).collect(Collectors.toList()));
}
diff --git a/src/main/java/seedu/savvytasker/ui/AliasSymbolCard.java b/src/main/java/seedu/savvytasker/ui/AliasSymbolCard.java
index 32d272f2be63..77ca5e554d54 100644
--- a/src/main/java/seedu/savvytasker/ui/AliasSymbolCard.java
+++ b/src/main/java/seedu/savvytasker/ui/AliasSymbolCard.java
@@ -22,10 +22,6 @@ public class AliasSymbolCard extends UiPart{
private AliasSymbol symbol;
private int displayedIndex;
- public AliasSymbolCard(){
-
- }
-
public static AliasSymbolCard load(AliasSymbol symbol, int displayedIndex){
AliasSymbolCard card = new AliasSymbolCard();
card.symbol = symbol;
diff --git a/src/main/java/seedu/savvytasker/ui/AliasSymbolListPanel.java b/src/main/java/seedu/savvytasker/ui/AliasSymbolListPanel.java
index 001aa10b1c50..85f8949f1b1e 100644
--- a/src/main/java/seedu/savvytasker/ui/AliasSymbolListPanel.java
+++ b/src/main/java/seedu/savvytasker/ui/AliasSymbolListPanel.java
@@ -27,10 +27,6 @@ public class AliasSymbolListPanel extends UiPart {
@FXML
private ListView aliasSymbolListView;
- public AliasSymbolListPanel() {
- super();
- }
-
@Override
public void setNode(Node node) {
panel = (VBox) node;
@@ -92,9 +88,6 @@ public void scrollTo(int index) {
class AliasSymbolListViewCell extends ListCell {
- public AliasSymbolListViewCell() {
- }
-
@Override
protected void updateItem(AliasSymbol symbol, boolean empty) {
super.updateItem(symbol, empty);
diff --git a/src/main/java/seedu/savvytasker/ui/CommandBox.java b/src/main/java/seedu/savvytasker/ui/CommandBox.java
old mode 100644
new mode 100755
index 81d26932aee4..e2d5d3c086d3
--- a/src/main/java/seedu/savvytasker/ui/CommandBox.java
+++ b/src/main/java/seedu/savvytasker/ui/CommandBox.java
@@ -1,5 +1,8 @@
+//@@author A0138431L
package seedu.savvytasker.ui;
+import java.io.File;
+import java.util.Stack;
import java.util.logging.Logger;
import com.google.common.eventbus.Subscribe;
@@ -8,7 +11,12 @@
import javafx.scene.Node;
import javafx.scene.control.SplitPane;
import javafx.scene.control.TextField;
+import javafx.scene.input.KeyCode;
+import javafx.scene.input.KeyCodeCombination;
+import javafx.scene.input.KeyCombination;
+import javafx.scene.input.KeyEvent;
import javafx.scene.layout.AnchorPane;
+import javafx.stage.DirectoryChooser;
import javafx.stage.Stage;
import seedu.savvytasker.commons.core.LogsCenter;
import seedu.savvytasker.commons.events.ui.IncorrectCommandAttemptedEvent;
@@ -24,6 +32,10 @@ public class CommandBox extends UiPart {
private AnchorPane commandPane;
private ResultDisplay resultDisplay;
String previousCommandTest;
+
+ // stack to store commands history
+ private static Stack COMMAND_HISTORY_STACK = new Stack();
+ private static Stack COMMAND_FUTURE_STACK = new Stack();
private Logic logic;
@@ -72,7 +84,8 @@ public void setPlaceholder(AnchorPane pane) {
private void handleCommandInputChanged() {
//Take a copy of the command text
previousCommandTest = commandTextField.getText();
-
+
+ COMMAND_HISTORY_STACK.push(previousCommandTest);
/* We assume the command is correct. If it is incorrect, the command box will be changed accordingly
* in the event handling code {@link #handleIncorrectCommandAttempted}
*/
@@ -102,7 +115,7 @@ private void handleIncorrectCommandAttempted(IncorrectCommandAttemptedEvent even
* Restores the command box text to the previously entered command
*/
private void restoreCommandText() {
- commandTextField.setText(previousCommandTest);
+ commandTextField.setText("");
}
/**
@@ -112,4 +125,186 @@ private void setStyleToIndicateIncorrectCommand() {
commandTextField.getStyleClass().add("error");
}
+ public Node getCommandTextField() {
+ return commandTextField;
+ }
+
+ //==================== Keyboard Shortcuts Code =================================================================
+ /**
+ * Key pressed handler for text box.
+ *
+ * @param keyEvent key event for the button that is being pressed.
+ */
+ public void commandTextFieldOnKeyPressedHandler(KeyEvent keyEvent) {
+
+ String userInput = commandTextField.getText().trim();
+
+ KeyCombination saveKey = new KeyCodeCombination(KeyCode.S, KeyCombination.META_DOWN);
+ KeyCombination undoKey = new KeyCodeCombination(KeyCode.Z, KeyCombination.META_DOWN);
+ KeyCombination redoKey = new KeyCodeCombination(KeyCode.Y, KeyCombination.META_DOWN);
+ KeyCombination helpKey = new KeyCodeCombination(KeyCode.H, KeyCombination.META_DOWN);
+ KeyCombination exitKey = new KeyCodeCombination(KeyCode.Q, KeyCombination.META_DOWN);
+ KeyCombination listKey = new KeyCodeCombination(KeyCode.L, KeyCombination.META_DOWN);
+ KeyCombination listArchivedKey = new KeyCodeCombination(KeyCode.A, KeyCombination.META_DOWN);
+ KeyCombination clearKey = new KeyCodeCombination(KeyCode.D, KeyCombination.META_DOWN);
+
+ try {
+
+ KeyCode keyCode = keyEvent.getCode();
+
+ if(saveKey.match(keyEvent)) {
+
+ processSave();
+
+ }else if (keyCode == KeyCode.ESCAPE) {
+
+ //close help dialog
+ //processEsc();
+
+ }else if (keyCode == KeyCode.UP) {
+
+ processUp(userInput);
+
+ } else if (keyCode == KeyCode.DOWN) {
+
+ processDown(userInput);
+
+ } else if (undoKey.match(keyEvent)) {
+
+ executeCommand("undo");
+
+ } else if (redoKey.match(keyEvent)) {
+
+ executeCommand("redo");
+
+ } else if (helpKey.match(keyEvent)) {
+
+ executeCommand("help");
+
+ } else if (exitKey.match(keyEvent)) {
+
+ executeCommand("exit");
+
+ } else if (listKey.match(keyEvent)) {
+
+ executeCommand("list");
+
+ } else if (listArchivedKey.match(keyEvent)) {
+
+ executeCommand("list t/Archived");
+
+ } else if (clearKey.match(keyEvent)) {
+
+ executeCommand("clear");
+
+ }
+
+ } catch (IllegalArgumentException e) {
+
+ commandTextField.setText("");
+
+ COMMAND_HISTORY_STACK.add(userInput);
+
+ this.logger.info("Illegal Argument has been entered.");
+
+ } catch (Exception e) {
+
+ e.printStackTrace();
+ commandTextField.setText("");
+
+ this.logger.info("Illegal Argument has been entered.");
+
+ }
+
+ }
+
+ /**
+ * Process the event that occurs after the user presses the ctrl-S button.
+ *
+ * @param userInput the command keyed in by the user.
+ */
+ public void processSave() {
+
+ //Execute the save command
+ DirectoryChooser directoryChooser = new DirectoryChooser();
+ File selectedFile = directoryChooser.showDialog(primaryStage);
+ String filepath = selectedFile.getAbsolutePath();
+ executeCommand("save " + filepath);
+
+ }
+
+ /**
+ * Process the event that occurs after the user presses the [ESC] button.
+ *
+ * @param userInput the command keyed in by the user.
+
+ public void processEsc() {
+
+ if (userInput.equals("") && isHelpViewVisible()) {
+
+ hideHelpView();
+
+ }
+
+ /**
+ * Process the event that occurs after the user presses the [UP] button.
+ *
+ * @param userInput the command keyed in by the user.
+ */
+ public void processUp(String userInput) {
+
+ if (!COMMAND_HISTORY_STACK.isEmpty()) {
+
+ String previousCommand = COMMAND_HISTORY_STACK.pop();
+
+ if (!userInput.equals("")) {
+
+ COMMAND_FUTURE_STACK.push(userInput);
+
+ }
+
+ commandTextField.setText(previousCommand);
+
+ }
+
+ commandTextField.positionCaret(commandTextField.getText().length());
+
+ }
+
+ /**
+ * Process the event that occurs after the user presses the down button.
+ *
+ * @param userInput the command keyed in by the user.
+ */
+ public void processDown(String userInput) {
+
+ if (!COMMAND_FUTURE_STACK.isEmpty()) {
+
+ String nextCommand = COMMAND_FUTURE_STACK.pop();
+
+ COMMAND_HISTORY_STACK.push(userInput);
+ commandTextField.setText(nextCommand);
+
+ } else if (!userInput.equals("")) {
+
+ COMMAND_HISTORY_STACK.push(userInput);
+ commandTextField.setText("");
+
+ }
+
+ commandTextField.positionCaret(commandTextField.getText().length());
+
+ }
+
+ /**
+ * Execute commands
+ *
+ * @param command to be executed
+ */
+ public void executeCommand(String commandInput) {
+ CommandResult commandResult = logic.execute(commandInput);
+ resultDisplay.postMessage(commandResult.feedbackToUser);
+ logger.info("Result: " + commandResult.feedbackToUser);
+ }
}
+
diff --git a/src/main/java/seedu/savvytasker/ui/DailyPanel.java b/src/main/java/seedu/savvytasker/ui/DailyPanel.java
new file mode 100644
index 000000000000..d94c16d0f800
--- /dev/null
+++ b/src/main/java/seedu/savvytasker/ui/DailyPanel.java
@@ -0,0 +1,158 @@
+package seedu.savvytasker.ui;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.logging.Logger;
+
+import javafx.application.Platform;
+import javafx.collections.ObservableList;
+import javafx.fxml.FXML;
+import javafx.scene.Node;
+import javafx.scene.control.Label;
+import javafx.scene.control.ListCell;
+import javafx.scene.control.ListView;
+import javafx.scene.control.SplitPane;
+import javafx.scene.layout.AnchorPane;
+import javafx.scene.layout.VBox;
+import javafx.stage.Stage;
+import seedu.savvytasker.commons.core.LogsCenter;
+import seedu.savvytasker.commons.events.ui.TaskPanelSelectionChangedEvent;
+import seedu.savvytasker.model.task.ReadOnlyTask;
+
+//@@author A0138431L
+
+/**
+ * Panel containing the list overdue task.
+ * @author A0138431L
+ *
+ */
+public class DailyPanel extends UiPart {
+
+ private static String TODAY_TITLE = "Today";
+ private static String TOMORROW_TITLE = "Tomorrow";
+ private static String DAY_PATTERN = "EEEE";
+ private static String DATE_PATTERN = "dd MMM yy";
+ private static String DAY_DATE_FORMAT = "%1$s, %2$s";
+
+ private final Logger logger = LogsCenter.getLogger(TaskListPanel.class);
+ private static final String FXML = "DailyList.fxml";
+ private VBox panel;
+ private AnchorPane placeHolderPane;
+
+ @FXML
+ private Label dayHeader;
+
+ @FXML
+ private ListView taskListView;
+
+ public DailyPanel() {
+ super();
+ }
+
+ @Override
+ public void setNode(Node node) {
+ panel = (VBox) node;
+ }
+
+ @Override
+ public String getFxmlPath() {
+ return FXML;
+ }
+
+ @Override
+ public void setPlaceholder(AnchorPane pane) {
+ this.placeHolderPane = pane;
+ }
+
+ public static DailyPanel load(Stage primaryStage, AnchorPane DailyListPlaceholder,
+ ObservableList taskList, int dayOfTheWeek, Date date) {
+ DailyPanel dailyPanel =
+ UiPartLoader.loadUiPart(primaryStage, DailyListPlaceholder, new DailyPanel());
+ dailyPanel.configure(taskList, dayOfTheWeek, date);
+ return dailyPanel;
+ }
+
+ private void configure(ObservableList taskList, int dayOfTheWeek, Date date) {
+
+ String dateHeader = generateHeader(dayOfTheWeek, date);
+ setConnections(taskList, dateHeader);
+ addToPlaceholder();
+ }
+
+ private void setConnections(ObservableList taskList, String dateHeader) {
+ dayHeader.setText(dateHeader);
+ taskListView.setItems(taskList);
+ taskListView.setCellFactory(listView -> new TaskListViewCell());
+ setEventHandlerForSelectionChangeEvent();
+ }
+
+ private void addToPlaceholder() {
+ SplitPane.setResizableWithParent(placeHolderPane, false);
+ placeHolderPane.getChildren().add(panel);
+ }
+
+ private void setEventHandlerForSelectionChangeEvent() {
+ taskListView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
+ if (newValue != null) {
+ logger.fine("Selection in daily task list panel changed to : '" + newValue + "'");
+ raise(new TaskPanelSelectionChangedEvent(newValue));
+ }
+ });
+ }
+
+ public void scrollTo(int index) {
+ Platform.runLater(() -> {
+ taskListView.scrollTo(index);
+ taskListView.getSelectionModel().clearAndSelect(index);
+ });
+ }
+
+ private String generateHeader(int dayOfTheWeek, Date date) {
+
+ SimpleDateFormat dayFormatter = new SimpleDateFormat(DAY_PATTERN);
+ SimpleDateFormat dateFormatter = new SimpleDateFormat(DATE_PATTERN);
+
+ String day;
+
+ switch (dayOfTheWeek) {
+
+ case 0:
+
+ day = TODAY_TITLE;
+ break;
+
+ case 1:
+
+ day = TOMORROW_TITLE;
+ break;
+
+ default:
+
+ day = dayFormatter.format(date);
+ break;
+
+ }
+ String header = String.format(DAY_DATE_FORMAT, day, dateFormatter.format(date));
+
+ return header;
+ }
+
+ class TaskListViewCell extends ListCell {
+
+ public TaskListViewCell() {
+ }
+
+ @Override
+ protected void updateItem(ReadOnlyTask task, boolean empty) {
+ super.updateItem(task, empty);
+
+ if (empty || task == null) {
+ setGraphic(null);
+ setText(null);
+ } else {
+ setGraphic(TaskCard.load(task, getIndex() + 1).getLayout());
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/seedu/savvytasker/ui/FloatingPanel.java b/src/main/java/seedu/savvytasker/ui/FloatingPanel.java
new file mode 100644
index 000000000000..dd32e6abe677
--- /dev/null
+++ b/src/main/java/seedu/savvytasker/ui/FloatingPanel.java
@@ -0,0 +1,112 @@
+package seedu.savvytasker.ui;
+
+import java.util.logging.Logger;
+
+import javafx.application.Platform;
+import javafx.collections.ObservableList;
+import javafx.fxml.FXML;
+import javafx.scene.Node;
+import javafx.scene.control.ListCell;
+import javafx.scene.control.ListView;
+import javafx.scene.control.SplitPane;
+import javafx.scene.layout.AnchorPane;
+import javafx.scene.layout.VBox;
+import javafx.stage.Stage;
+import seedu.savvytasker.commons.core.LogsCenter;
+import seedu.savvytasker.commons.events.ui.TaskPanelSelectionChangedEvent;
+import seedu.savvytasker.model.task.ReadOnlyTask;
+
+//@@author A0138431L
+
+/**
+ * Panel containing the list floating task.
+ * @author A0138431L
+ *
+ */
+public class FloatingPanel extends UiPart {
+ private final Logger logger = LogsCenter.getLogger(TaskListPanel.class);
+ private static final String FXML = "FloatingList.fxml";
+ private VBox panel;
+ private AnchorPane placeHolderPane;
+
+ @FXML
+ private ListView taskListView;
+
+ public FloatingPanel() {
+ super();
+ }
+
+ @Override
+ public void setNode(Node node) {
+ panel = (VBox) node;
+ }
+
+ @Override
+ public String getFxmlPath() {
+ return FXML;
+ }
+
+ @Override
+ public void setPlaceholder(AnchorPane pane) {
+ this.placeHolderPane = pane;
+ }
+
+ public static FloatingPanel load(Stage primaryStage, AnchorPane floatingListPlaceholder,
+ ObservableList taskList) {
+ FloatingPanel floatingPanel =
+ UiPartLoader.loadUiPart(primaryStage, floatingListPlaceholder, new FloatingPanel());
+ floatingPanel.configure(taskList);
+ return floatingPanel;
+ }
+
+ private void configure(ObservableList taskList) {
+ setConnections(taskList);
+ addToPlaceholder();
+ }
+
+ private void setConnections(ObservableList taskList) {
+ taskListView.setItems(taskList);
+ taskListView.setCellFactory(listView -> new TaskListViewCell());
+ setEventHandlerForSelectionChangeEvent();
+ }
+
+ private void addToPlaceholder() {
+ SplitPane.setResizableWithParent(placeHolderPane, false);
+ placeHolderPane.getChildren().add(panel);
+ }
+
+ private void setEventHandlerForSelectionChangeEvent() {
+ taskListView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
+ if (newValue != null) {
+ logger.fine("Selection in floating task list panel changed to : '" + newValue + "'");
+ raise(new TaskPanelSelectionChangedEvent(newValue));
+ }
+ });
+ }
+
+ public void scrollTo(int index) {
+ Platform.runLater(() -> {
+ taskListView.scrollTo(index);
+ taskListView.getSelectionModel().clearAndSelect(index);
+ });
+ }
+
+ class TaskListViewCell extends ListCell {
+
+ public TaskListViewCell() {
+ }
+
+ @Override
+ protected void updateItem(ReadOnlyTask task, boolean empty) {
+ super.updateItem(task, empty);
+
+ if (empty || task == null) {
+ setGraphic(null);
+ setText(null);
+ } else {
+ setGraphic(TaskCard.load(task, getIndex() + 1).getLayout());
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/seedu/savvytasker/ui/HelpWindow.java b/src/main/java/seedu/savvytasker/ui/HelpWindow.java
old mode 100644
new mode 100755
index 63df34b43afa..f98e4d5b0357
--- a/src/main/java/seedu/savvytasker/ui/HelpWindow.java
+++ b/src/main/java/seedu/savvytasker/ui/HelpWindow.java
@@ -59,4 +59,10 @@ private void configure(){
public void show() {
dialogStage.showAndWait();
}
+
+ public void hide() {
+
+ dialogStage.hide();
+
+ }
}
diff --git a/src/main/java/seedu/savvytasker/ui/MainWindow.java b/src/main/java/seedu/savvytasker/ui/MainWindow.java
old mode 100644
new mode 100755
index 1974651a4ecc..c1eb8c6a6c5f
--- a/src/main/java/seedu/savvytasker/ui/MainWindow.java
+++ b/src/main/java/seedu/savvytasker/ui/MainWindow.java
@@ -1,5 +1,13 @@
+//@@author A0138431L
+
package seedu.savvytasker.ui;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+
+import com.google.common.eventbus.Subscribe;
+
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.Scene;
@@ -8,8 +16,11 @@
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
+
import seedu.savvytasker.commons.core.Config;
import seedu.savvytasker.commons.core.GuiSettings;
+import seedu.savvytasker.commons.core.LogsCenter;
+import seedu.savvytasker.commons.events.model.SavvyTaskerChangedEvent;
import seedu.savvytasker.commons.events.ui.ExitAppRequestEvent;
import seedu.savvytasker.logic.Logic;
import seedu.savvytasker.model.UserPrefs;
@@ -17,41 +28,63 @@
/**
* The Main Window. Provides the basic application layout containing
- * a menu bar and space where other JavaFX elements can be placed.
+ * a sorting and filtered list that display the result of the user command
+ * on the left and a week's view of the task
+ *
+ * The week's view contains 4 lists, namely the floating list, overdue list,
+ * days of the week list and upcoming list
+ *
+ * Floating list contains task without start and end dateTime
+ * Overdue list contains task with end date before current date
+ * Days of the week list contains task that falls on the respective day of the selected week
+ * Upcoming list contains task with start date after the last day of selected week
+ *
+ * @author A0138431L
+ *
*/
public class MainWindow extends UiPart {
- private static final String ICON = "/images/address_book_32.png";
- private static final String FXML = "MainWindow.fxml";
- public static final int MIN_HEIGHT = 600;
- public static final int MIN_WIDTH = 450;
+ private static final String ICON = "/images/address_book_32.png";
+ private static final String FXML = "MainWindow.fxml";
+ public static final int MIN_HEIGHT = 700;
+ public static final int MIN_WIDTH = 1150;
- private Logic logic;
+ private Logic logic;
+ Date date = new Date();
+ private static int DAYS_OF_WEEK = 7;
- // Independent Ui parts residing in this Ui container
- private BrowserPanel browserPanel;
- private TaskListPanel taskListPanel;
+ // Independent Ui parts residing in this Ui container
+ //private BrowserPanel browserPanel;
+ private TaskListPanel taskListPanel;
private AliasSymbolListPanel aliasSymbolListPanel;
- private ResultDisplay resultDisplay;
- private StatusBarFooter statusBarFooter;
- private CommandBox commandBox;
- private Config config;
- private UserPrefs userPrefs;
-
- // Handles to elements of this Ui container
- private VBox rootLayout;
- private Scene scene;
-
- private String addressBookName;
-
- @FXML
- private AnchorPane browserPlaceholder;
-
- @FXML
- private AnchorPane commandBoxPlaceholder;
-
- @FXML
- private MenuItem helpMenuItem;
+ private ResultDisplay resultDisplay;
+ private StatusBarFooter statusBarFooter;
+ private CommandBox commandBox;
+ private Config config;
+ private UserPrefs userPrefs;
+ @FXML
+ private FloatingPanel floatingPanel;
+ @FXML
+ private OverduePanel overduePanel;
+ @FXML
+ private DailyPanel dailyPanel;
+ @FXML
+ private UpcomingPanel upcomingPanel;
+
+ // Handles to elements of this Ui container
+ private VBox rootLayout;
+ private Scene scene;
+
+ private String addressBookName;
+
+ @FXML
+ private AnchorPane browserPlaceholder;
+
+ @FXML
+ private AnchorPane commandBoxPlaceholder;
+
+ @FXML
+ private MenuItem helpMenuItem;
@FXML
private AnchorPane taskListPanelPlaceholder;
@@ -59,72 +92,108 @@ public class MainWindow extends UiPart {
@FXML
private AnchorPane aliasSymbolListPanelPlaceholder;
- @FXML
- private AnchorPane resultDisplayPlaceholder;
+ @FXML
+ private AnchorPane resultDisplayPlaceholder;
+
+ @FXML
+ private AnchorPane statusbarPlaceholder;
- @FXML
- private AnchorPane statusbarPlaceholder;
-
@FXML
private VBox listPanel;
- public MainWindow() {
- super();
- }
-
- @Override
- public void setNode(Node node) {
- rootLayout = (VBox) node;
- }
-
- @Override
- public String getFxmlPath() {
- return FXML;
- }
-
- public static MainWindow load(Stage primaryStage, Config config, UserPrefs prefs, Logic logic) {
-
- MainWindow mainWindow = UiPartLoader.loadUiPart(primaryStage, new MainWindow());
- mainWindow.configure(config.getAppTitle(), config.getSavvyTaskerListName(), config, prefs, logic);
- return mainWindow;
- }
-
- private void configure(String appTitle, String addressBookName, Config config, UserPrefs prefs,
- Logic logic) {
-
- //Set dependencies
- this.logic = logic;
- this.addressBookName = addressBookName;
- this.config = config;
- this.userPrefs = prefs;
-
- //Configure the UI
- setTitle(appTitle);
- setIcon(ICON);
- setWindowMinSize();
- setWindowDefaultSize(prefs);
- scene = new Scene(rootLayout);
- primaryStage.setScene(scene);
-
- setAccelerators();
- }
-
- private void setAccelerators() {
- helpMenuItem.setAccelerator(KeyCombination.valueOf("F1"));
- }
-
- void fillInnerParts() {
- browserPanel = BrowserPanel.load(browserPlaceholder);
+ @FXML
+ private AnchorPane floatingPanelPlaceholder;
+
+ @FXML
+ private AnchorPane overduePanelPlaceholder;
+
+ @FXML
+ private AnchorPane day1PanelPlaceholder;
+ @FXML
+ private AnchorPane day2PanelPlaceholder;
+ @FXML
+ private AnchorPane day3PanelPlaceholder;
+ @FXML
+ private AnchorPane day4PanelPlaceholder;
+ @FXML
+ private AnchorPane day5PanelPlaceholder;
+ @FXML
+ private AnchorPane day6PanelPlaceholder;
+ @FXML
+ private AnchorPane day7PanelPlaceholder;
+
+ @FXML
+ private AnchorPane upcomingPanelPlaceholder;
+
+ public MainWindow() {
+ super();
+ }
+
+ @Override
+ public void setNode(Node node) {
+ rootLayout = (VBox) node;
+ }
+
+ @Override
+ public String getFxmlPath() {
+ return FXML;
+ }
+
+ public static MainWindow load(Stage primaryStage, Config config, UserPrefs prefs, Logic logic) {
+
+ MainWindow mainWindow = UiPartLoader.loadUiPart(primaryStage, new MainWindow());
+ mainWindow.configure(config.getAppTitle(), config.getSavvyTaskerListName(), config, prefs, logic);
+ return mainWindow;
+ }
+
+ private void configure(String appTitle, String addressBookName, Config config, UserPrefs prefs,
+ Logic logic) {
+
+ //Set dependencies
+ this.logic = logic;
+ this.addressBookName = addressBookName;
+ this.config = config;
+ this.userPrefs = prefs;
+ registerAsAnEventHandler(this);
+
+ //Configure the UI
+ setTitle(appTitle);
+ setIcon(ICON);
+ setWindowMinSize();
+ setWindowDefaultSize(prefs);
+ scene = new Scene(rootLayout);
+ primaryStage.setScene(scene);
+
+ }
+
+ void fillInnerParts() {
+ //browserPanel = BrowserPanel.load(browserPlaceholder);
taskListPanel = TaskListPanel.load(primaryStage, getTaskListPlaceholder(), logic.getFilteredTaskList());
aliasSymbolListPanel = AliasSymbolListPanel.load(primaryStage, getAliasSymbolPlaceholder(), logic.getAliasSymbolList());
setDefaultView();
- resultDisplay = ResultDisplay.load(primaryStage, getResultDisplayPlaceholder());
- statusBarFooter = StatusBarFooter.load(primaryStage, getStatusbarPlaceholder(), config.getSavvyTaskerFilePath());
- commandBox = CommandBox.load(primaryStage, getCommandBoxPlaceholder(), resultDisplay, logic);
- }
-
- /**
+
+ resultDisplay = ResultDisplay.load(primaryStage, getResultDisplayPlaceholder());
+ statusBarFooter = StatusBarFooter.load(primaryStage, getStatusbarPlaceholder(), config.getSavvyTaskerFilePath());
+ commandBox = CommandBox.load(primaryStage, getCommandBoxPlaceholder(), resultDisplay, logic);
+ commandBox.getCommandTextField().requestFocus();
+ floatingPanel = FloatingPanel.load(primaryStage, getFloatingPanelPlaceholder(), logic.getFilteredFloatingTasks());
+ overduePanel = OverduePanel.load(primaryStage, getOverduePanelPlaceholder(), logic.getFilteredOverdueTasks());
+ loadDailyPanel();
+ upcomingPanel = UpcomingPanel.load(primaryStage, getUpcomingPanelPlaceholder(), logic.getFilteredUpcomingTasks(date));
+ }
+
+ private void loadDailyPanel() {
+ for (int i = 0; i < DAYS_OF_WEEK; i++) {
+ Date onDate = new Date();
+ onDate.setTime(date.getTime());
+ onDate = addDay(i, onDate);
+ dailyPanel = DailyPanel.load(primaryStage, getDailyPanelPlaceholder(i),
+ logic.getFilteredDailyTasks(i, onDate), i, onDate);
+ }
+ }
+
+ /**
* Removes all the children in the taskPanel VBox
* Shows the default list, which is the list of tasks
*/
@@ -152,17 +221,17 @@ private VBox getListPanel() {
return listPanel;
}
- private AnchorPane getCommandBoxPlaceholder() {
- return commandBoxPlaceholder;
- }
+ private AnchorPane getCommandBoxPlaceholder() {
+ return commandBoxPlaceholder;
+ }
- private AnchorPane getStatusbarPlaceholder() {
- return statusbarPlaceholder;
- }
+ private AnchorPane getStatusbarPlaceholder() {
+ return statusbarPlaceholder;
+ }
- private AnchorPane getResultDisplayPlaceholder() {
- return resultDisplayPlaceholder;
- }
+ private AnchorPane getResultDisplayPlaceholder() {
+ return resultDisplayPlaceholder;
+ }
public AnchorPane getTaskListPlaceholder() {
return taskListPanelPlaceholder;
@@ -172,6 +241,71 @@ public AnchorPane getAliasSymbolPlaceholder() {
return aliasSymbolListPanelPlaceholder;
}
+ private AnchorPane getFloatingPanelPlaceholder() {
+ return floatingPanelPlaceholder;
+ }
+
+ private AnchorPane getOverduePanelPlaceholder() {
+ return overduePanelPlaceholder;
+ }
+
+ private AnchorPane getDailyPanelPlaceholder(int index) {
+
+ switch(index) {
+
+ case 0:
+
+ return day1PanelPlaceholder;
+
+ case 1:
+
+ return day2PanelPlaceholder;
+
+ case 2:
+
+ return day3PanelPlaceholder;
+
+ case 3:
+
+ return day4PanelPlaceholder;
+
+ case 4:
+
+ return day5PanelPlaceholder;
+
+ case 5:
+
+ return day6PanelPlaceholder;
+
+ case 6:
+
+ return day7PanelPlaceholder;
+
+ default:
+
+ return day1PanelPlaceholder;
+ }
+
+ }
+
+ private AnchorPane getUpcomingPanelPlaceholder() {
+ return upcomingPanelPlaceholder;
+ }
+
+ private Date addDay(int i, Date date) {
+
+ //convert date object to calendar object and add 1 days
+ Calendar calendarExpectedDate = Calendar.getInstance();
+ calendarExpectedDate.setTime(date);
+
+ calendarExpectedDate.add(Calendar.DATE, i);
+
+ //convert calendar object back to date object
+ date = calendarExpectedDate.getTime();
+
+ return date;
+ }
+
public void hide() {
primaryStage.hide();
}
@@ -180,10 +314,10 @@ private void setTitle(String appTitle) {
primaryStage.setTitle(appTitle);
}
- /**
- * Sets the default size based on user preferences.
- */
- protected void setWindowDefaultSize(UserPrefs prefs) {
+ /**
+ * Sets the default size based on user preferences.
+ */
+ protected void setWindowDefaultSize(UserPrefs prefs) {
primaryStage.setHeight(prefs.getGuiSettings().getWindowHeight());
primaryStage.setWidth(prefs.getGuiSettings().getWindowWidth());
if (prefs.getGuiSettings().getWindowCoordinates() != null) {
@@ -198,11 +332,11 @@ private void setWindowMinSize() {
}
/**
- * Returns the current size and the position of the main Window.
- */
+ * Returns the current size and the position of the main Window.
+ */
public GuiSettings getCurrentGuiSetting() {
return new GuiSettings(primaryStage.getWidth(), primaryStage.getHeight(),
- (int) primaryStage.getX(), (int) primaryStage.getY());
+ (int) primaryStage.getX(), (int) primaryStage.getY());
}
@FXML
@@ -210,14 +344,19 @@ public void handleHelp() {
HelpWindow helpWindow = HelpWindow.load(primaryStage);
helpWindow.show();
}
+
+ public void hideHelp() {
+ HelpWindow helpWindow = HelpWindow.load(primaryStage);
+ helpWindow.hide();
+ }
- public void show() {
- primaryStage.show();
+ public void show() {
+ primaryStage.show();
}
/**
- * Closes the application.
- */
+ * Closes the application.
+ */
@FXML
private void handleExit() {
raise(new ExitAppRequestEvent());
@@ -231,11 +370,18 @@ public TaskListPanel getTaskListPanel() {
return this.taskListPanel;
}
- public void loadPersonPage(ReadOnlyTask task) {
- browserPanel.loadPersonPage(task);
+
+ public void loadPersonPage(ReadOnlyTask task) {
+ //browserPanel.loadPersonPage(task);
+ }
+
+ public void releaseResources() {
+ //browserPanel.freeResources();
}
- public void releaseResources() {
- browserPanel.freeResources();
+ @Subscribe
+ public void handleSavvyTaskerChangedEvent(SavvyTaskerChangedEvent stce) {
+ loadDailyPanel();
}
-}
+
+}
\ No newline at end of file
diff --git a/src/main/java/seedu/savvytasker/ui/OverduePanel.java b/src/main/java/seedu/savvytasker/ui/OverduePanel.java
new file mode 100644
index 000000000000..b4eba1935b7d
--- /dev/null
+++ b/src/main/java/seedu/savvytasker/ui/OverduePanel.java
@@ -0,0 +1,112 @@
+package seedu.savvytasker.ui;
+
+import java.util.logging.Logger;
+
+import javafx.application.Platform;
+import javafx.collections.ObservableList;
+import javafx.fxml.FXML;
+import javafx.scene.Node;
+import javafx.scene.control.ListCell;
+import javafx.scene.control.ListView;
+import javafx.scene.control.SplitPane;
+import javafx.scene.layout.AnchorPane;
+import javafx.scene.layout.VBox;
+import javafx.stage.Stage;
+import seedu.savvytasker.commons.core.LogsCenter;
+import seedu.savvytasker.commons.events.ui.TaskPanelSelectionChangedEvent;
+import seedu.savvytasker.model.task.ReadOnlyTask;
+
+//@@author A0138431L
+
+/**
+* Panel containing the list overdue task.
+* @author A0138431L
+*
+*/
+public class OverduePanel extends UiPart {
+ private final Logger logger = LogsCenter.getLogger(TaskListPanel.class);
+ private static final String FXML = "OverdueList.fxml";
+ private VBox panel;
+ private AnchorPane placeHolderPane;
+
+ @FXML
+ private ListView taskListView;
+
+ public OverduePanel() {
+ super();
+ }
+
+ @Override
+ public void setNode(Node node) {
+ panel = (VBox) node;
+ }
+
+ @Override
+ public String getFxmlPath() {
+ return FXML;
+ }
+
+ @Override
+ public void setPlaceholder(AnchorPane pane) {
+ this.placeHolderPane = pane;
+ }
+
+ public static OverduePanel load(Stage primaryStage, AnchorPane overdueListPlaceholder,
+ ObservableList taskList) {
+ OverduePanel oveduePanel =
+ UiPartLoader.loadUiPart(primaryStage, overdueListPlaceholder, new OverduePanel());
+ oveduePanel.configure(taskList);
+ return oveduePanel;
+ }
+
+ private void configure(ObservableList taskList) {
+ setConnections(taskList);
+ addToPlaceholder();
+ }
+
+ private void setConnections(ObservableList taskList) {
+ taskListView.setItems(taskList);
+ taskListView.setCellFactory(listView -> new TaskListViewCell());
+ setEventHandlerForSelectionChangeEvent();
+ }
+
+ private void addToPlaceholder() {
+ SplitPane.setResizableWithParent(placeHolderPane, false);
+ placeHolderPane.getChildren().add(panel);
+ }
+
+ private void setEventHandlerForSelectionChangeEvent() {
+ taskListView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
+ if (newValue != null) {
+ logger.fine("Selection in overdue task list panel changed to : '" + newValue + "'");
+ raise(new TaskPanelSelectionChangedEvent(newValue));
+ }
+ });
+ }
+
+ public void scrollTo(int index) {
+ Platform.runLater(() -> {
+ taskListView.scrollTo(index);
+ taskListView.getSelectionModel().clearAndSelect(index);
+ });
+ }
+
+ class TaskListViewCell extends ListCell {
+
+ public TaskListViewCell() {
+ }
+
+ @Override
+ protected void updateItem(ReadOnlyTask task, boolean empty) {
+ super.updateItem(task, empty);
+
+ if (empty || task == null) {
+ setGraphic(null);
+ setText(null);
+ } else {
+ setGraphic(TaskCard.load(task, getIndex() + 1).getLayout());
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/seedu/savvytasker/ui/ResultDisplay.java b/src/main/java/seedu/savvytasker/ui/ResultDisplay.java
index 8f7dce90e194..ca5b0396047b 100644
--- a/src/main/java/seedu/savvytasker/ui/ResultDisplay.java
+++ b/src/main/java/seedu/savvytasker/ui/ResultDisplay.java
@@ -37,6 +37,7 @@ public void configure() {
resultDisplayArea.getStyleClass().add(STATUS_BAR_STYLE_SHEET);
resultDisplayArea.setText("");
resultDisplayArea.textProperty().bind(displayed);
+ resultDisplayArea.setStyle("-fx-text-fill: white;");
FxViewUtil.applyAnchorBoundaryParameters(resultDisplayArea, 0.0, 0.0, 0.0, 0.0);
mainPane.getChildren().add(resultDisplayArea);
FxViewUtil.applyAnchorBoundaryParameters(mainPane, 0.0, 0.0, 0.0, 0.0);
diff --git a/src/main/java/seedu/savvytasker/ui/StatusBarFooter.java b/src/main/java/seedu/savvytasker/ui/StatusBarFooter.java
index 482171f30520..0b1df76eea51 100644
--- a/src/main/java/seedu/savvytasker/ui/StatusBarFooter.java
+++ b/src/main/java/seedu/savvytasker/ui/StatusBarFooter.java
@@ -92,7 +92,7 @@ public String getFxmlPath() {
return FXML;
}
- //@@author A0139915W
+ //@@author A0138431L
@Subscribe
public void handleSavvyTaskerSaveLocationChangedEvent(DataSavingLocationChangedEvent dslce) {
setSaveLocation(dslce.newPath);
diff --git a/src/main/java/seedu/savvytasker/ui/TaskCard.java b/src/main/java/seedu/savvytasker/ui/TaskCard.java
index 5d3512c8b5de..d978f9229316 100644
--- a/src/main/java/seedu/savvytasker/ui/TaskCard.java
+++ b/src/main/java/seedu/savvytasker/ui/TaskCard.java
@@ -9,6 +9,10 @@
public class TaskCard extends UiPart{
private static final String FXML = "TaskListCard.fxml";
+
+ public static final String LOW_PRIORITY_BACKGROUND = "-fx-background-color:#CEFFDC";
+ public static final String MEDIUM_PRIORITY_BACKGROUND = "-fx-background-color:#FFFED8";
+ public static final String HIGH_PRIORITY_BACKGROUND = "-fx-background-color:#FF8180";
@FXML
private HBox cardPane;
@@ -22,10 +26,6 @@ public class TaskCard extends UiPart{
private ReadOnlyTask task;
private int displayedIndex;
- public TaskCard(){
-
- }
-
public static TaskCard load(ReadOnlyTask task, int displayedIndex){
TaskCard card = new TaskCard();
card.task = task;
@@ -38,12 +38,32 @@ public void initialize() {
taskName.setText(task.getTaskName());
id.setText(displayedIndex + ". ");
details.setText(task.getTextForUi());
+ setCardBackground();
}
public HBox getLayout() {
return cardPane;
}
-
+
+ private void setCardBackground() {
+
+ if (task.getPriority().toString().equals("High")) {
+
+ cardPane.setStyle(HIGH_PRIORITY_BACKGROUND);
+
+ } else if (task.getPriority().toString().equals("Medium")) {
+
+ cardPane.setStyle(MEDIUM_PRIORITY_BACKGROUND);
+
+ } else if (task.getPriority().toString().equals("Low")) {
+
+ cardPane.setStyle(LOW_PRIORITY_BACKGROUND);
+
+ }
+
+ }
+
+
@Override
public void setNode(Node node) {
cardPane = (HBox)node;
diff --git a/src/main/java/seedu/savvytasker/ui/TaskListPanel.java b/src/main/java/seedu/savvytasker/ui/TaskListPanel.java
index f90ea46f78fd..56b053ec13b1 100644
--- a/src/main/java/seedu/savvytasker/ui/TaskListPanel.java
+++ b/src/main/java/seedu/savvytasker/ui/TaskListPanel.java
@@ -28,10 +28,6 @@ public class TaskListPanel extends UiPart {
@FXML
private ListView taskListView;
- public TaskListPanel() {
- super();
- }
-
@Override
public void setNode(Node node) {
panel = (VBox) node;
@@ -93,9 +89,6 @@ public void scrollTo(int index) {
class TaskListViewCell extends ListCell {
- public TaskListViewCell() {
- }
-
@Override
protected void updateItem(ReadOnlyTask task, boolean empty) {
super.updateItem(task, empty);
diff --git a/src/main/java/seedu/savvytasker/ui/UpcomingPanel.java b/src/main/java/seedu/savvytasker/ui/UpcomingPanel.java
new file mode 100644
index 000000000000..6c374a4410d7
--- /dev/null
+++ b/src/main/java/seedu/savvytasker/ui/UpcomingPanel.java
@@ -0,0 +1,112 @@
+package seedu.savvytasker.ui;
+
+import java.util.logging.Logger;
+
+import javafx.application.Platform;
+import javafx.collections.ObservableList;
+import javafx.fxml.FXML;
+import javafx.scene.Node;
+import javafx.scene.control.ListCell;
+import javafx.scene.control.ListView;
+import javafx.scene.control.SplitPane;
+import javafx.scene.layout.AnchorPane;
+import javafx.scene.layout.VBox;
+import javafx.stage.Stage;
+import seedu.savvytasker.commons.core.LogsCenter;
+import seedu.savvytasker.commons.events.ui.TaskPanelSelectionChangedEvent;
+import seedu.savvytasker.model.task.ReadOnlyTask;
+
+//@@author A0138431L
+
+/**
+* Panel containing the list overdue task.
+* @author A0138431L
+*
+*/
+public class UpcomingPanel extends UiPart {
+ private final Logger logger = LogsCenter.getLogger(TaskListPanel.class);
+ private static final String FXML = "UpcomingList.fxml";
+ private VBox panel;
+ private AnchorPane placeHolderPane;
+
+ @FXML
+ private ListView taskListView;
+
+ public UpcomingPanel() {
+ super();
+ }
+
+ @Override
+ public void setNode(Node node) {
+ panel = (VBox) node;
+ }
+
+ @Override
+ public String getFxmlPath() {
+ return FXML;
+ }
+
+ @Override
+ public void setPlaceholder(AnchorPane pane) {
+ this.placeHolderPane = pane;
+ }
+
+ public static UpcomingPanel load(Stage primaryStage, AnchorPane UpcomingListPlaceholder,
+ ObservableList taskList) {
+ UpcomingPanel upcomingPanel =
+ UiPartLoader.loadUiPart(primaryStage, UpcomingListPlaceholder, new UpcomingPanel());
+ upcomingPanel.configure(taskList);
+ return upcomingPanel;
+ }
+
+ private void configure(ObservableList taskList) {
+ setConnections(taskList);
+ addToPlaceholder();
+ }
+
+ private void setConnections(ObservableList taskList) {
+ taskListView.setItems(taskList);
+ taskListView.setCellFactory(listView -> new TaskListViewCell());
+ setEventHandlerForSelectionChangeEvent();
+ }
+
+ private void addToPlaceholder() {
+ SplitPane.setResizableWithParent(placeHolderPane, false);
+ placeHolderPane.getChildren().add(panel);
+ }
+
+ private void setEventHandlerForSelectionChangeEvent() {
+ taskListView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
+ if (newValue != null) {
+ logger.fine("Selection in upcoming task list panel changed to : '" + newValue + "'");
+ raise(new TaskPanelSelectionChangedEvent(newValue));
+ }
+ });
+ }
+
+ public void scrollTo(int index) {
+ Platform.runLater(() -> {
+ taskListView.scrollTo(index);
+ taskListView.getSelectionModel().clearAndSelect(index);
+ });
+ }
+
+ class TaskListViewCell extends ListCell {
+
+ public TaskListViewCell() {
+ }
+
+ @Override
+ protected void updateItem(ReadOnlyTask task, boolean empty) {
+ super.updateItem(task, empty);
+
+ if (empty || task == null) {
+ setGraphic(null);
+ setText(null);
+ } else {
+ setGraphic(TaskCard.load(task, getIndex() + 1).getLayout());
+ }
+ }
+ }
+
+}
diff --git a/src/main/resources/view/CommandBox.fxml b/src/main/resources/view/CommandBox.fxml
index d2267909fd5c..1b27d75c643b 100644
--- a/src/main/resources/view/CommandBox.fxml
+++ b/src/main/resources/view/CommandBox.fxml
@@ -1,9 +1,8 @@
-
-
-
-
+
+
+
+
diff --git a/src/main/resources/view/DailyList.fxml b/src/main/resources/view/DailyList.fxml
new file mode 100644
index 000000000000..0ad3c5149b13
--- /dev/null
+++ b/src/main/resources/view/DailyList.fxml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/view/DarkTheme.css b/src/main/resources/view/DarkTheme.css
old mode 100644
new mode 100755
index 8043b344253a..1efb0b72e305
--- a/src/main/resources/view/DarkTheme.css
+++ b/src/main/resources/view/DarkTheme.css
@@ -122,7 +122,11 @@
}
.result-display {
- -fx-background-color: #ffffff;
+ -fx-background-color: transparent;
+}
+
+.result-display .content {
+ -fx-background-color: #383838;
}
.result-display .label {
@@ -285,4 +289,187 @@
#filterField, #personListPanel, #personWebpage {
-fx-effect: innershadow(gaussian, black, 10, 0, 0, 0);
+}
+
+#taskListView {
+ -fx-background-color: transparent;
+}
+/*------------------------------------------ OverduePanel Styling ------------------------------------------*/
+
+.overdue-scrollpane, .overdue-panel {
+ -fx-background-color:#DCFFFD;
+}
+
+.overdue-scrollpane > .scroll-bar:horizontal .thumb,
+.overdue-scrollpane > .scroll-bar:vertical .thumb {
+ -fx-background-color:#99534D;
+}
+
+.overdue-panel .title, .overdue-panel .taskname {
+ -fx-text-fill:#000000;
+}
+
+.overdue-panel .subtitle, .overdue-panel .timestamp {
+ -fx-text-fill:#B26059;
+}
+
+/*------------------------------------------ FloatingPanel Styling ------------------------------------------*/
+
+.floating-scrollpane, .floating-panel {
+ -fx-background-color:#ACEDFF;
+}
+
+.floating-scrollpane {
+ -fx-border-radius: 15px;
+}
+
+.floating-scrollpane > .scroll-bar:horizontal .thumb,
+.floating-scrollpane > .scroll-bar:vertical .thumb {
+ -fx-background-color:#406C7F;
+}
+
+.floating-panel .title, .floating-panel .taskname {
+ -fx-text-fill:#000000;
+}
+
+.floating-panel .subtitle, .floating-panel .timestamp {
+ -fx-text-fill:#5997BS2;
+}
+
+/*------------------------------------------ DailyPanel Styling ------------------------------------------*/
+
+.daily-scrollpane, .daily-panel {
+ -fx-background-color:#99D3FF;
+}
+
+.daily-scrollpane > .scroll-bar:horizontal .thumb,
+.daily-scrollpane > .scroll-bar:vertical .thumb {
+ -fx-background-color:#7E7E45;
+}
+
+.daily-panel .title, .daily-panel .taskname {
+ -fx-text-fill:#5D5D33;
+}
+
+.daily-panel .subtitle, .daily-panel .timestamp {
+ -fx-text-fill:#B2B262;
+}
+
+/*------------------------------------------ UpcomingPanel Styling ------------------------------------------*/
+.upcoming-scrollpane, .upcoming-panel {
+ -fx-background-color:#D1E0FF;
+}
+
+.upcoming-scrollpane > .scroll-bar:horizontal .thumb,
+.upcoming-scrollpane > .scroll-bar:vertical .thumb {
+ -fx-background-color:#657E47;
+}
+
+.upcoming-panel .check-box > .box {
+ -fx-border-color:#657E47;
+}
+
+.upcoming-panel .check-box {
+ -fx-font-family:'Helvetica';
+ -fx-text-fill:#485A33;
+ -fx-font-size:10;
+ -fx-font-weight:bold;
+}
+
+.upcoming-panel .title, .upcoming-panel .taskname {
+ -fx-text-fill:#485A33;
+}
+
+.upcoming-panel .subtitle, .upcoming-panel .timestamp {
+ -fx-text-fill:#8EB264;
+}
+
+/*------------------------------------------ ArchivedPanel Styling ------------------------------------------*/
+
+.archived-panel .title {
+ -fx-font-family:'Helvetica Condensed';
+ -fx-font-size:24;
+ -fx-font-weight:normal;
+}
+
+.archived-panel .taskname, .archived-panel .timestamp {
+ -fx-text-fill:#FFFFFF;
+}
+
+/*------------------------------------------ SearchPanel Styling ------------------------------------------*/
+
+.search-view-title {
+ -fx-font-family:'Helvetica Condensed';
+ -fx-font-size:24;
+ -fx-font-weight:normal;
+}
+
+.search-panel .title {
+ -fx-font-family:'Helvetica Condensed';
+ -fx-font-size:20;
+ -fx-font-weight:normal;
+}
+
+.search-panel .check-box {
+ -fx-font-family:'Helvetica';
+ -fx-text-fill:#FFFFFF;
+ -fx-font-size:10;
+ -fx-font-weight:bold;
+}
+
+.search-panel .taskname, .search-panel .timestamp {
+ -fx-text-fill:#FFFFFF;
+}
+
+/*------------------------------------------ HelpPanel Styling ------------------------------------------*/
+
+.help-panel .title {
+ -fx-font-family:'Helvetica Bold';
+ -fx-font-size:48;
+ -fx-font-weight:normal;
+}
+
+.help-panel .subtitle {
+ -fx-font-family:'Helvetica';
+ -fx-font-size:13;
+ -fx-font-weight:bold;
+}
+
+.overlay-scrollpane, .overlay-scrollpane > .viewport {
+ -fx-background-color:transparent;
+}
+
+.scroll-pane > .scroll-bar:horizontal,
+.scroll-pane > .scroll-bar:vertical {
+ -fx-background-color:transparent;
+ -fx-background-radius:2em;
+ -fx-border-radius:2em;
+}
+
+.scorll-pane > .scroll-bar:horizontal .track,
+.scroll-pane > .scroll-bar:vertical .track {
+ -fx-background-color:transparent;
+ -fx-background-radius:0em;
+ -fx-border-color:transparent;
+ -fx-border-radius:2em;
+}
+
+.scroll-pane > .scroll-bar:horizontal .thumb,
+.scroll-pane > .scroll-bar:vertical .thumb {
+ -fx-background-insets:4, 5, 6;
+ -fx-background-radius:2em;
+ -fx-border-radius:2em;
+}
+
+.scroll-pane > .scroll-bar > .increment-button,
+.scroll-pane > .scroll-bar > .decrement-button {
+ -fx-background-color:transparent;
+ -fx-background-radius:0em;
+ -fx-padding:0 0 10 0;
+}
+
+.scroll-pane > .scroll-bar > .increment-button > .increment-arrow,
+.scroll-pane > .scroll-bar > .decrement-button > .decrement-arrow {
+ -fx-shape:" ";
+ -fx-padding:0;
}
\ No newline at end of file
diff --git a/src/main/resources/view/FloatingList.fxml b/src/main/resources/view/FloatingList.fxml
new file mode 100644
index 000000000000..8d58ccc772b8
--- /dev/null
+++ b/src/main/resources/view/FloatingList.fxml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/view/MainWindow.fxml b/src/main/resources/view/MainWindow.fxml
old mode 100644
new mode 100755
index e2567ee9ad65..9c39bab158f1
--- a/src/main/resources/view/MainWindow.fxml
+++ b/src/main/resources/view/MainWindow.fxml
@@ -1,55 +1,130 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
-
+
+
+
+
-
-
-
-
-
-
+
-
+
-
+
-
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/view/OverdueList.fxml b/src/main/resources/view/OverdueList.fxml
new file mode 100644
index 000000000000..ab5ca805ad79
--- /dev/null
+++ b/src/main/resources/view/OverdueList.fxml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/view/PersonListCard.fxml b/src/main/resources/view/PersonListCard.fxml
new file mode 100755
index 000000000000..9953ce588beb
--- /dev/null
+++ b/src/main/resources/view/PersonListCard.fxml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/view/PersonListPanel.fxml b/src/main/resources/view/PersonListPanel.fxml
new file mode 100755
index 000000000000..aa9c30ae99eb
--- /dev/null
+++ b/src/main/resources/view/PersonListPanel.fxml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/main/resources/view/TaskListCard.fxml b/src/main/resources/view/TaskListCard.fxml
old mode 100644
new mode 100755
index 2df104257f29..987e7b0ec451
--- a/src/main/resources/view/TaskListCard.fxml
+++ b/src/main/resources/view/TaskListCard.fxml
@@ -12,7 +12,7 @@
-
+
diff --git a/src/main/resources/view/UpcomingList.fxml b/src/main/resources/view/UpcomingList.fxml
new file mode 100644
index 000000000000..8cd68484bb65
--- /dev/null
+++ b/src/main/resources/view/UpcomingList.fxml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/java/guitests/AddCommandTest.java b/src/test/java/guitests/AddCommandTest.java
index becd062d5121..ae4fc28569d2 100644
--- a/src/test/java/guitests/AddCommandTest.java
+++ b/src/test/java/guitests/AddCommandTest.java
@@ -20,6 +20,9 @@
//@@author A0139915W
public class AddCommandTest extends SavvyTaskerGuiTest {
+ private DateFormat formatter = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.getDefault());
+ private SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
+
@Test
public void add() {
//add one task
@@ -61,8 +64,7 @@ private void assertAddSuccess(TestTask taskToAdd, TestTask... currentList) {
TestTask[] expectedList = TestUtil.addTasksToList(currentList, taskToAdd);
assertTrue(taskListPanel.isListMatching(expectedList));
}
-
- private DateFormat formatter = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.getDefault());
+
private String getLocaleDateString(Date date) {
try {
return formatter.format(date);
@@ -72,7 +74,6 @@ private String getLocaleDateString(Date date) {
return null;
}
- private SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
private Date getDate(String ddmmyyyy) {
try {
return format.parse(ddmmyyyy);
diff --git a/src/test/java/guitests/CommandBoxTest.java b/src/test/java/guitests/CommandBoxTest.java
index dbd8b655d036..ef2111d47438 100644
--- a/src/test/java/guitests/CommandBoxTest.java
+++ b/src/test/java/guitests/CommandBoxTest.java
@@ -13,9 +13,9 @@ public void commandBox_commandSucceeds_textCleared() {
}
@Test
- public void commandBox_commandFails_textStays(){
+ public void commandBox_commandFails_textClears(){
commandBox.runCommand("invalid command");
- assertEquals(commandBox.getCommandInput(), "invalid command");
+ assertEquals(commandBox.getCommandInput(), "");
//TODO: confirm the text box color turns to red
}
diff --git a/src/test/java/guitests/DeleteCommandTest.java b/src/test/java/guitests/DeleteCommandTest.java
index 7dfe77dbc734..bb0f13f9b730 100644
--- a/src/test/java/guitests/DeleteCommandTest.java
+++ b/src/test/java/guitests/DeleteCommandTest.java
@@ -17,11 +17,9 @@ public void delete() {
//delete the first in the list
TestTask[] currentList = td.getTypicalTasks();
int targetIndex = 1;
-
assertDeleteSuccess(targetIndex, currentList);
//delete the last in the list
-
currentList = TestUtil.removeTaskFromList(currentList, targetIndex);
targetIndex = currentList.length;
assertDeleteSuccess(targetIndex, currentList);
diff --git a/src/test/java/guitests/HelpWindowTest.java b/src/test/java/guitests/HelpWindowTest.java
index 988156dd3dec..0b84c09ceb78 100644
--- a/src/test/java/guitests/HelpWindowTest.java
+++ b/src/test/java/guitests/HelpWindowTest.java
@@ -12,9 +12,11 @@ public void openHelpWindow() {
taskListPanel.clickOnListView();
- assertHelpWindowOpen(mainMenu.openHelpWindowUsingAccelerator());
+ // Feature removed
+ //assertHelpWindowOpen(mainMenu.openHelpWindowUsingAccelerator());
- assertHelpWindowOpen(mainMenu.openHelpWindowUsingMenu());
+ // Feature removed
+ //assertHelpWindowOpen(mainMenu.openHelpWindowUsingMenu());
assertHelpWindowOpen(commandBox.runHelpCommand());
diff --git a/src/test/java/guitests/ModifyCommandTest.java b/src/test/java/guitests/ModifyCommandTest.java
index fddc833fe95e..a57ed8f57d2d 100644
--- a/src/test/java/guitests/ModifyCommandTest.java
+++ b/src/test/java/guitests/ModifyCommandTest.java
@@ -18,6 +18,9 @@
//@@author A0139915W
public class ModifyCommandTest extends SavvyTaskerGuiTest {
+ private DateFormat formatter = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.getDefault());
+ private SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
+
@Test
public void add() {
//modify task
@@ -60,7 +63,6 @@ private void assertModifySuccess(String command, TestTask taskToModify, TestTask
assertTrue(taskListPanel.isListMatching(expectedList));
}
- private DateFormat formatter = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.getDefault());
private String getLocaleDateString(Date date) {
try {
return formatter.format(date);
@@ -70,7 +72,6 @@ private String getLocaleDateString(Date date) {
return null;
}
- private SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
private Date getDate(String ddmmyyyy) {
try {
return format.parse(ddmmyyyy);
diff --git a/src/test/java/guitests/RedoCommandTest.java b/src/test/java/guitests/RedoCommandTest.java
new file mode 100644
index 000000000000..00a77efc1dbc
--- /dev/null
+++ b/src/test/java/guitests/RedoCommandTest.java
@@ -0,0 +1,152 @@
+//@@author A0097627N
+package guitests;
+
+import guitests.guihandles.TaskCardHandle;
+
+import org.junit.Test;
+
+import seedu.savvytasker.logic.commands.UndoCommand;
+import seedu.savvytasker.logic.commands.RedoCommand;
+import seedu.savvytasker.logic.commands.HelpCommand;
+import seedu.savvytasker.testutil.TestTask;
+import seedu.savvytasker.testutil.TestUtil;
+
+import static org.junit.Assert.assertTrue;
+import static seedu.savvytasker.commons.core.Messages.MESSAGE_UNKNOWN_COMMAND;
+import static seedu.savvytasker.logic.commands.RedoCommand.MESSAGE_REDO_ACKNOWLEDGEMENT;
+
+public class RedoCommandTest extends SavvyTaskerGuiTest {
+
+ TestTask[] expectedList = td.getTypicalTasks();
+ TestTask[] currentList = td.getTypicalTasks();
+ TestTask firstTaskToAdd = td.happy;
+ TestTask secondTaskToAdd = td.haloween;
+ TestTask pjmTaskToAdd = td.pjm;
+ TestTask projectMeetingTaskToAdd = td.projectMeeting;
+
+ @Test
+ // redo one add command
+ public void redoAddTest() {
+ expectedList = TestUtil.addTasksToList(currentList, firstTaskToAdd);
+ commandBox.runCommand(firstTaskToAdd.getAddCommand());
+ commandBox.runCommand("undo");
+ commandBox.runCommand("redo");
+ assertTrue(taskListPanel.isListMatching(expectedList));
+ assertResultMessage(MESSAGE_REDO_ACKNOWLEDGEMENT);
+ }
+
+ @Test
+ // redo a delete command
+ public void redoDeleteTest() {
+ expectedList = TestUtil.removeTaskFromList(currentList, 1);
+ commandBox.runCommand("delete 1");
+ commandBox.runCommand("undo");
+ commandBox.runCommand("redo");
+ assertTrue(taskListPanel.isListMatching(expectedList));
+ assertResultMessage(MESSAGE_REDO_ACKNOWLEDGEMENT);
+ }
+
+ @Test
+ // redo clear command
+ public void redoClearTest() {
+ commandBox.runCommand("clear");
+ commandBox.runCommand("undo");
+ commandBox.runCommand("redo");
+ assertListSize(0);
+ assertResultMessage(MESSAGE_REDO_ACKNOWLEDGEMENT);
+ }
+
+ @Test
+ // redo alias command
+ public void redoAliasTest() {
+ expectedList = td.getTypicalTasks();
+ expectedList = TestUtil.addTasksToList(expectedList, projectMeetingTaskToAdd);
+ commandBox.runCommand("alias k/pjm r/Project Meeting");
+ commandBox.runCommand("undo");
+ commandBox.runCommand("redo");
+ assertResultMessage(MESSAGE_REDO_ACKNOWLEDGEMENT);
+ commandBox.runCommand(pjmTaskToAdd.getAddCommand());
+ assertTrue(taskListPanel.isListMatching(expectedList));
+ }
+
+ @Test
+ // redo unalias command
+ public void redoUnaliasTest() {
+ expectedList = TestUtil.addTasksToList(currentList, pjmTaskToAdd);
+ commandBox.runCommand("alias k/pjm r/Project Meeting");
+ commandBox.runCommand("unalias pjm");
+ commandBox.runCommand("undo");
+ commandBox.runCommand("redo");
+ assertResultMessage(MESSAGE_REDO_ACKNOWLEDGEMENT);
+ commandBox.runCommand(pjmTaskToAdd.getAddCommand());
+ assertTrue(taskListPanel.isListMatching(expectedList));
+ }
+
+ // redo two add commands
+ @Test
+ public void redoTwoAddTest() {
+ expectedList = TestUtil.addTasksToList(currentList, firstTaskToAdd);
+ expectedList = TestUtil.addTasksToList(expectedList, secondTaskToAdd);
+ commandBox.runCommand(firstTaskToAdd.getAddCommand());
+ commandBox.runCommand(secondTaskToAdd.getAddCommand());
+ commandBox.runCommand("undo");
+ commandBox.runCommand("undo");
+ commandBox.runCommand("redo");
+ commandBox.runCommand("redo");
+ assertTrue(taskListPanel.isListMatching(expectedList));
+ assertResultMessage(MESSAGE_REDO_ACKNOWLEDGEMENT);
+ }
+
+ // redo two delete commands
+ @Test
+ public void redoTwoDeleteTest() {
+ expectedList = TestUtil.removeTaskFromList(currentList, 1);
+ expectedList = TestUtil.removeTaskFromList(expectedList, 1);
+ commandBox.runCommand("delete 1");
+ commandBox.runCommand("delete 1");
+ commandBox.runCommand("undo");
+ commandBox.runCommand("undo");
+ commandBox.runCommand("redo");
+ commandBox.runCommand("redo");
+ assertTrue(taskListPanel.isListMatching(expectedList));
+ assertResultMessage(MESSAGE_REDO_ACKNOWLEDGEMENT);
+ }
+
+ // redo a delete command followed by an add command
+ @Test
+ public void redoDeleteAddTest() {
+ expectedList = TestUtil.addTasksToList(currentList, firstTaskToAdd);
+ expectedList = TestUtil.removeTaskFromList(expectedList, 1);
+ commandBox.runCommand(firstTaskToAdd.getAddCommand());
+ commandBox.runCommand("delete 1");
+ commandBox.runCommand("undo");
+ commandBox.runCommand("undo");
+ commandBox.runCommand("redo");
+ commandBox.runCommand("redo");
+ assertTrue(taskListPanel.isListMatching(expectedList));
+ assertResultMessage(MESSAGE_REDO_ACKNOWLEDGEMENT);
+ }
+
+ // redo an add command followed by a delete command
+ @Test
+ public void redoAddDeleteTest() {
+ expectedList = TestUtil.removeTaskFromList(currentList, 1);
+ expectedList = TestUtil.addTasksToList(expectedList, firstTaskToAdd);
+ commandBox.runCommand("delete 1");
+ commandBox.runCommand(firstTaskToAdd.getAddCommand());
+ commandBox.runCommand("undo");
+ commandBox.runCommand("undo");
+ commandBox.runCommand("redo");
+ commandBox.runCommand("redo");
+ assertTrue(taskListPanel.isListMatching(expectedList));
+ assertResultMessage(MESSAGE_REDO_ACKNOWLEDGEMENT);
+ }
+
+ // invalid command
+ @Test
+ public void invalidTest() {
+ commandBox.runCommand("redos");
+ assertResultMessage("Input: redos\n" + String.format(MESSAGE_UNKNOWN_COMMAND, HelpCommand.MESSAGE_USAGE));
+ }
+}
+//@@author
\ No newline at end of file
diff --git a/src/test/java/guitests/UndoCommandTest.java b/src/test/java/guitests/UndoCommandTest.java
new file mode 100644
index 000000000000..813c06479a81
--- /dev/null
+++ b/src/test/java/guitests/UndoCommandTest.java
@@ -0,0 +1,145 @@
+//@@author A0097627N
+package guitests;
+
+import guitests.guihandles.TaskCardHandle;
+
+import org.junit.Test;
+
+import seedu.savvytasker.logic.commands.UndoCommand;
+import seedu.savvytasker.logic.commands.HelpCommand;
+import seedu.savvytasker.testutil.TestTask;
+import seedu.savvytasker.testutil.TestUtil;
+
+import static org.junit.Assert.assertTrue;
+import static seedu.savvytasker.commons.core.Messages.MESSAGE_UNKNOWN_COMMAND;
+import static seedu.savvytasker.logic.commands.UndoCommand.MESSAGE_UNDO_ACKNOWLEDGEMENT;
+
+public class UndoCommandTest extends SavvyTaskerGuiTest {
+
+ TestTask[] expectedList = td.getTypicalTasks();
+ TestTask[] currentList = td.getTypicalTasks();
+ TestTask firstTaskToAdd = td.happy;
+ TestTask secondTaskToAdd = td.haloween;
+ TestTask pjmTaskToAdd = td.pjm;
+ TestTask projectMeetingTaskToAdd = td.projectMeeting;
+
+ @Test
+ // undo one add command
+ public void undoAddTest() {
+ expectedList = td.getTypicalTasks();
+ commandBox.runCommand(firstTaskToAdd.getAddCommand());
+ commandBox.runCommand("undo");
+ assertTrue(taskListPanel.isListMatching(expectedList));
+ assertResultMessage(MESSAGE_UNDO_ACKNOWLEDGEMENT);
+ }
+
+ @Test
+ // undo a delete command
+ public void undoDeleteTest() {
+ expectedList = td.getTypicalTasks();
+ commandBox.runCommand("delete 1");
+ commandBox.runCommand("undo");
+ assertTrue(taskListPanel.isListMatching(expectedList));
+ assertResultMessage(MESSAGE_UNDO_ACKNOWLEDGEMENT);
+ }
+
+ @Test
+ // undo clear command
+ public void undoClearTest() {
+ expectedList = td.getTypicalTasks();
+ commandBox.runCommand("clear");
+ commandBox.runCommand("undo");
+ assertTrue(taskListPanel.isListMatching(expectedList));
+ assertResultMessage(MESSAGE_UNDO_ACKNOWLEDGEMENT);
+ }
+
+ @Test
+ // undo alias command
+ public void undoAliasTest() {
+ expectedList = td.getTypicalTasks();
+ expectedList = TestUtil.addTasksToList(expectedList, pjmTaskToAdd);
+ commandBox.runCommand("alias k/pjm r/Project Meeting");
+ commandBox.runCommand("undo");
+ assertResultMessage(MESSAGE_UNDO_ACKNOWLEDGEMENT);
+ commandBox.runCommand(pjmTaskToAdd.getAddCommand());
+ assertTrue(taskListPanel.isListMatching(expectedList));
+ }
+
+ @Test
+ // undo unalias command
+ public void undoUnaliasTest() {
+ expectedList = TestUtil.addTasksToList(currentList, projectMeetingTaskToAdd);
+ commandBox.runCommand("alias k/pjm r/Project Meeting");
+ commandBox.runCommand("unalias pjm");
+ commandBox.runCommand("undo");
+ assertResultMessage(MESSAGE_UNDO_ACKNOWLEDGEMENT);
+ commandBox.runCommand(pjmTaskToAdd.getAddCommand());
+ assertTrue(taskListPanel.isListMatching(expectedList));
+ }
+
+ // undo mark command
+ @Test
+ public void undoMarkTest() {
+ expectedList = td.getTypicalTasks();
+ commandBox.runCommand("mark 1");
+ commandBox.runCommand("undo");
+ assertTrue(taskListPanel.isListMatching(expectedList));
+ assertResultMessage(MESSAGE_UNDO_ACKNOWLEDGEMENT);
+ }
+
+ // undo two add commands
+ @Test
+ public void undoTwoAddTest() {
+ expectedList = td.getTypicalTasks();
+ commandBox.runCommand(firstTaskToAdd.getAddCommand());
+ commandBox.runCommand(secondTaskToAdd.getAddCommand());
+ commandBox.runCommand("undo");
+ commandBox.runCommand("undo");
+ assertTrue(taskListPanel.isListMatching(expectedList));
+ assertResultMessage(MESSAGE_UNDO_ACKNOWLEDGEMENT);
+ }
+
+ // undo two delete commands
+ @Test
+ public void undoTwoDeleteTest() {
+ expectedList = td.getTypicalTasks();
+ commandBox.runCommand("delete 1");
+ commandBox.runCommand("delete 1");
+ commandBox.runCommand("undo");
+ commandBox.runCommand("undo");
+ assertTrue(taskListPanel.isListMatching(expectedList));
+ assertResultMessage(MESSAGE_UNDO_ACKNOWLEDGEMENT);
+ }
+
+ // undo a delete command followed by an add command
+ @Test
+ public void undoDeleteAddTest() {
+ expectedList = td.getTypicalTasks();
+ commandBox.runCommand(firstTaskToAdd.getAddCommand());
+ commandBox.runCommand("delete 1");
+ commandBox.runCommand("undo");
+ commandBox.runCommand("undo");
+ assertTrue(taskListPanel.isListMatching(expectedList));
+ assertResultMessage(MESSAGE_UNDO_ACKNOWLEDGEMENT);
+ }
+
+ // undo an add command followed by a delete command
+ @Test
+ public void undoAddDeleteTest() {
+ expectedList = td.getTypicalTasks();
+ commandBox.runCommand("delete 1");
+ commandBox.runCommand(firstTaskToAdd.getAddCommand());
+ commandBox.runCommand("undo");
+ commandBox.runCommand("undo");
+ assertTrue(taskListPanel.isListMatching(expectedList));
+ assertResultMessage(MESSAGE_UNDO_ACKNOWLEDGEMENT);
+ }
+
+ // invalid command
+ @Test
+ public void invalidTest() {
+ commandBox.runCommand("undos");
+ assertResultMessage("Input: undos\n" + String.format(MESSAGE_UNKNOWN_COMMAND, HelpCommand.MESSAGE_USAGE));
+ }
+}
+// @@author
diff --git a/src/test/java/seedu/savvytasker/commons/util/SmartDefaultDatesTest.java b/src/test/java/seedu/savvytasker/commons/util/SmartDefaultDatesTest.java
index 6fe7ca6fc358..d8598a8eecf2 100644
--- a/src/test/java/seedu/savvytasker/commons/util/SmartDefaultDatesTest.java
+++ b/src/test/java/seedu/savvytasker/commons/util/SmartDefaultDatesTest.java
@@ -15,6 +15,8 @@
//@@author A0139915W
public class SmartDefaultDatesTest {
+ private SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HHmmss");
+
@Test
public void smartDefaultDates_parseStart() {
DateParser dateParser = new DateParser();
@@ -29,10 +31,9 @@ public void smartDefaultDates_parseStart() {
SmartDefaultDates sdd = new SmartDefaultDates(inferredStart, inferredEnd);
// specifying only start date, assumed to on the given date at 12am
// and to end on the given date at 2359:59
- Date expectedStartTime = getDate("31/12/2016 000000");
- Date expectedEndTime = getDate("31/12/2016 235959");
- assertEquals(expectedStartTime, sdd.getStartDate());
- assertEquals(expectedEndTime, sdd.getEndDate());
+ assertStartEndEquals(
+ getDate("31/12/2016 000000"), getDate("31/12/2016 235959"),
+ sdd.getStartDate(), sdd.getEndDate());
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date today = today(0, 0);
@@ -45,10 +46,9 @@ public void smartDefaultDates_parseStart() {
sdd = new SmartDefaultDates(inferredStart, inferredEnd);
// specifying only start time, assumed to start today at the given time
// and to end today 2359:59
- expectedStartTime = getDate(sdf.format(today) + " 150000");
- expectedEndTime = getDate(sdf.format(today) + " 235959");
- assertEquals(expectedStartTime, sdd.getStartDate());
- assertEquals(expectedEndTime, sdd.getEndDate());
+ assertStartEndEquals(
+ getDate(sdf.format(today) + " 150000"), getDate(sdf.format(today) + " 235959"),
+ sdd.getStartDate(), sdd.getEndDate());
}
@Test
@@ -67,10 +67,9 @@ public void smartDefaultDates_parseEnd() {
SmartDefaultDates sdd = new SmartDefaultDates(inferredStart, inferredEnd);
// specified only the end date, assumed to start today at 12am
// and to end on the given date at 2359:59
- Date expectedStartTime = getDate(sdf.format(today) + " 000000");
- Date expectedEndTime = getDate("31/12/2016 235959");
- assertEquals(expectedStartTime, sdd.getStartDate());
- assertEquals(expectedEndTime, sdd.getEndDate());
+ assertStartEndEquals(
+ getDate(sdf.format(today) + " 000000"), getDate("31/12/2016 235959"),
+ sdd.getStartDate(), sdd.getEndDate());
try {
//use MM-dd-yyyy
@@ -81,10 +80,9 @@ public void smartDefaultDates_parseEnd() {
sdd = new SmartDefaultDates(inferredStart, inferredEnd);
// specified only the end time, assumed to start today at 12am
// and to end at the given time today
- expectedStartTime = getDate(sdf.format(today) + " 000000");
- expectedEndTime = getDate(sdf.format(today) + " 150000");
- assertEquals(expectedStartTime, sdd.getStartDate());
- assertEquals(expectedEndTime, sdd.getEndDate());
+ assertStartEndEquals(
+ getDate(sdf.format(today) + " 000000"), getDate(sdf.format(today) + " 150000"),
+ sdd.getStartDate(), sdd.getEndDate());
try {
@@ -96,10 +94,9 @@ public void smartDefaultDates_parseEnd() {
sdd = new SmartDefaultDates(inferredStart, inferredEnd);
// specified only the end date in the past, start date will be null
// and to end on the given date at 2359:59
- expectedStartTime = null;
- expectedEndTime = getDate("31/12/2000 235959");
- assertEquals(expectedStartTime, sdd.getStartDate());
- assertEquals(expectedEndTime, sdd.getEndDate());
+ assertStartEndEquals(
+ null, getDate("31/12/2000 235959"),
+ sdd.getStartDate(), sdd.getEndDate());
}
@Test
@@ -126,10 +123,9 @@ public void smartDefaultDates_parseStartEnd() {
// no time supplied for start and end
// start defaults to 0000
// end defaults to 2359:59
- Date expectedStartTime = getDate("31/12/2016 000000");
- Date expectedEndTime = getDate("31/12/2016 235959");
- assertEquals(expectedStartTime, sdd.getStartDate());
- assertEquals(expectedEndTime, sdd.getEndDate());
+ assertStartEndEquals(
+ getDate("31/12/2016 000000"), getDate("31/12/2016 235959"),
+ sdd.getStartDate(), sdd.getEndDate());
inferredStart = null;
inferredEnd = null;
@@ -145,10 +141,9 @@ public void smartDefaultDates_parseStartEnd() {
// start defaults to 0000
// end defaults to 2359:59
// no restrictions imposed on end time earlier than start time
- expectedStartTime = getDate("31/12/2016 000000");
- expectedEndTime = getDate("30/12/2016 235959");
- assertEquals(expectedStartTime, sdd.getStartDate());
- assertEquals(expectedEndTime, sdd.getEndDate());
+ assertStartEndEquals(
+ getDate("31/12/2016 000000"), getDate("30/12/2016 235959"),
+ sdd.getStartDate(), sdd.getEndDate());
inferredStart = null;
inferredEnd = null;
@@ -162,10 +157,9 @@ public void smartDefaultDates_parseStartEnd() {
sdd = new SmartDefaultDates(inferredStart, inferredEnd);
// no date supplied for start and end
// start and end defaults to the given time today
- expectedStartTime = getDate(sdf.format(today) + " 100000");
- expectedEndTime = getDate(sdf.format(today) + " 220000");
- assertEquals(expectedStartTime, sdd.getStartDate());
- assertEquals(expectedEndTime, sdd.getEndDate());
+ assertStartEndEquals(
+ getDate(sdf.format(today) + " 100000"), getDate(sdf.format(today) + " 220000"),
+ sdd.getStartDate(), sdd.getEndDate());
inferredStart = null;
inferredEnd = null;
@@ -180,10 +174,9 @@ public void smartDefaultDates_parseStartEnd() {
// no date supplied for start and end, end time ends before start time
// start and end defaults to the given time today
// no restrictions imposed on end time being earlier
- expectedStartTime = getDate(sdf.format(today) + " 220000");
- expectedEndTime = getDate(sdf.format(today) + " 100000");
- assertEquals(expectedStartTime, sdd.getStartDate());
- assertEquals(expectedEndTime, sdd.getEndDate());
+ assertStartEndEquals(
+ getDate(sdf.format(today) + " 220000"), getDate(sdf.format(today) + " 100000"),
+ sdd.getStartDate(), sdd.getEndDate());
}
@Test
@@ -194,10 +187,8 @@ public void smartDefaultDates_defaultParse() {
SmartDefaultDates sdd = new SmartDefaultDates(null, null);
Date actualStart = sdd.getStart(dateParser.new InferredDate(new Date(), true, true));
Date actualEnd = sdd.getEnd(dateParser.new InferredDate(new Date(), true, true));
- Date expectedStart = null;
- Date expectedEnd = null;
- assertEquals(expectedStart, actualStart);
- assertEquals(expectedEnd, actualEnd);
+ assertStartEndEquals(null, null,
+ actualStart, actualEnd);
try {
//use MM-dd-yyyy
@@ -206,10 +197,9 @@ public void smartDefaultDates_defaultParse() {
} catch (ParseException e) {
assert false; //won't get here
}
- expectedStart = getDate(sdf.format(today) + " 220000");
- expectedEnd = getDate(sdf.format(today) + " 100000");
- assertEquals(expectedStart, actualStart);
- assertEquals(expectedEnd, actualEnd);
+ assertStartEndEquals(
+ getDate(sdf.format(today) + " 220000"), getDate(sdf.format(today) + " 100000"),
+ actualStart, actualEnd);
try {
//use MM-dd-yyyy
@@ -218,13 +208,16 @@ public void smartDefaultDates_defaultParse() {
} catch (ParseException e) {
assert false; //won't get here
}
- expectedStart = getDate("31/12/2016 000000");
- expectedEnd = getDate("31/12/2016 235959");
+ assertStartEndEquals(getDate("31/12/2016 000000"), getDate("31/12/2016 235959"),
+ actualStart, actualEnd);
+ }
+
+ private void assertStartEndEquals(Date expectedStart, Date expectedEnd,
+ Date actualStart, Date actualEnd) {
assertEquals(expectedStart, actualStart);
assertEquals(expectedEnd, actualEnd);
}
- private SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HHmmss");
private Date getDate(String ddmmyyyy) {
try {
return format.parse(ddmmyyyy);
diff --git a/src/test/java/seedu/savvytasker/logic/LogicManagerTest.java b/src/test/java/seedu/savvytasker/logic/LogicManagerTest.java
index 9b59af423a5e..a5682f25e361 100644
--- a/src/test/java/seedu/savvytasker/logic/LogicManagerTest.java
+++ b/src/test/java/seedu/savvytasker/logic/LogicManagerTest.java
@@ -3,7 +3,6 @@
import com.google.common.eventbus.Subscribe;
import seedu.savvytasker.commons.core.EventsCenter;
-import seedu.savvytasker.commons.core.Messages;
import seedu.savvytasker.commons.core.UnmodifiableObservableList;
import seedu.savvytasker.commons.events.model.SavvyTaskerChangedEvent;
import seedu.savvytasker.commons.events.ui.JumpToListRequestEvent;
@@ -49,7 +48,7 @@ public class LogicManagerTest {
//These are for checking the correctness of the events raised
private ReadOnlySavvyTasker latestSavedSavvyTasker;
private boolean helpShown;
- private int targetedJumpIndex;
+ //private int targetedJumpIndex;
@Subscribe
private void handleLocalModelChangedEvent(SavvyTaskerChangedEvent stce) {
@@ -63,7 +62,7 @@ private void handleShowHelpRequestEvent(ShowHelpRequestEvent she) {
@Subscribe
private void handleJumpToListRequestEvent(JumpToListRequestEvent je) {
- targetedJumpIndex = je.targetIndex;
+ //targetedJumpIndex = je.targetIndex;
}
@Before
@@ -76,7 +75,7 @@ public void setup() {
latestSavedSavvyTasker = new SavvyTasker(model.getSavvyTasker()); // last saved assumed to be up to date before.
helpShown = false;
- targetedJumpIndex = -1; // non yet
+ //targetedJumpIndex = -1; // non yet
}
@After
@@ -196,12 +195,12 @@ private void assertIncorrectIndexFormatBehaviorForCommand(String commandWord, St
// the following commands outputs a different expected message dealing with
// invalid indices.
- expectedMessage = "Input: delete -1\n" + String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.COMMAND_FORMAT) + ": " + IndexParser.INDEX_MUST_BE_POSITIVE;
- assertCommandBehavior(commandWord + " -1", expectedMessage); //index should be unsigned
- expectedMessage = "Input: delete 0\n" + String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.COMMAND_FORMAT) + ": " + IndexParser.INDEX_MUST_BE_POSITIVE;
- assertCommandBehavior(commandWord + " 0", expectedMessage); //index cannot be 0
- expectedMessage = "Input: delete not_a_number\n" + String.format(Messages.MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.COMMAND_FORMAT) + ": " + IndexParser.INDEX_MUST_BE_POSITIVE;
- assertCommandBehavior(commandWord + " not_a_number", expectedMessage);
+ String newExpectedMessage = "Input: delete -1\n" + String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.COMMAND_FORMAT) + ": " + IndexParser.INDEX_MUST_BE_POSITIVE;
+ assertCommandBehavior(commandWord + " -1", newExpectedMessage); //index should be unsigned
+ newExpectedMessage = "Input: delete 0\n" + String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.COMMAND_FORMAT) + ": " + IndexParser.INDEX_MUST_BE_POSITIVE;
+ assertCommandBehavior(commandWord + " 0", newExpectedMessage); //index cannot be 0
+ newExpectedMessage = "Input: delete not_a_number\n" + String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.COMMAND_FORMAT) + ": " + IndexParser.INDEX_MUST_BE_POSITIVE;
+ assertCommandBehavior(commandWord + " not_a_number", newExpectedMessage);
}
/**
diff --git a/src/test/java/seedu/savvytasker/testutil/TestUtil.java b/src/test/java/seedu/savvytasker/testutil/TestUtil.java
index 348a28c5e37b..3ced67abe8ab 100644
--- a/src/test/java/seedu/savvytasker/testutil/TestUtil.java
+++ b/src/test/java/seedu/savvytasker/testutil/TestUtil.java
@@ -38,7 +38,11 @@
* A utility class for test cases.
*/
public class TestUtil {
-
+ /**
+ * Folder used for temp files created during testing. Ignored by Git.
+ */
+ public static String SANDBOX_FOLDER = FileUtil.getPath("./src/test/data/sandbox/");
+ public static final Task[] sampleTaskData = getSampleTaskData();
public static String LS = System.lineSeparator();
public static void assertThrows(Class extends Throwable> expected, Runnable executable) {
@@ -56,13 +60,7 @@ public static void assertThrows(Class extends Throwable> expected, Runnable ex
String.format("Expected %s to be thrown, but nothing was thrown.", expected.getName()));
}
- /**
- * Folder used for temp files created during testing. Ignored by Git.
- */
- public static String SANDBOX_FOLDER = FileUtil.getPath("./src/test/data/sandbox/");
-
//@@author A0139915W
- public static final Task[] sampleTaskData = getSampleTaskData();
private static Task[] getSampleTaskData() {
return new Task[]{
diff --git a/src/test/java/seedu/savvytasker/testutil/TypicalTestTasks.java b/src/test/java/seedu/savvytasker/testutil/TypicalTestTasks.java
index 31f80cda0527..bfff6d3faa63 100644
--- a/src/test/java/seedu/savvytasker/testutil/TypicalTestTasks.java
+++ b/src/test/java/seedu/savvytasker/testutil/TypicalTestTasks.java
@@ -16,7 +16,7 @@
public class TypicalTestTasks {
public TestTask highPriority, medPriority, lowPriority, furthestDue,
- nearerDue, notSoNearerDue, earliestDue, longDue, happy, haloween;
+ nearerDue, notSoNearerDue, earliestDue, longDue, happy, haloween, pjm, projectMeeting;
private SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
public TypicalTestTasks() {
@@ -41,6 +41,8 @@ public TypicalTestTasks() {
//Manually added
happy = new TaskBuilder().withId(9).withTaskName("Happy Task").build();
haloween = new TaskBuilder().withId(10).withTaskName("Haloween Task").build();
+ pjm = new TaskBuilder().withId(11).withTaskName("pjm").build();
+ projectMeeting = new TaskBuilder().withId(12).withTaskName("Project Meeting").build();
} catch (IllegalValueException e) {
e.printStackTrace();
assert false : "not possible";