Project: Mobilize

Mobilize is a organizing and planning desktop address book application used for teaching Software Engineering principles. The user interacts with it using a CLI, and it has a GUI created with JavaFX. It is written in Java, and has about 6 kLoC.

Code contributed: [Functional code] [Test code]

Enhancement Added: switch

External behavior


Start of Extract [from: User Guide]

Switching Between Address Book and Task Manager : switch

To help you save time to remember all the commands in Mobilize, you can toggle between address book and task manager using:

Format: switch addressbook or switch taskmanager

You can use ab for addressbook and tm for taskmanager in the command.
The default mode of Mobilize will be address book.

End of Extract


Justification

With the integration of address book and task manager, users are required to memorize many commands. User would need to type a longer command keyword such as: addtask and addperson.

Hence, adding switch command mode feature allows user to remember less commands. It will shorten the command keywords from addtask and addperson to just add.

Implementation


Start of Extract [from: Developer Guide]

SwitchMode mechanism

The switchMode mechanism is facilitated by the ChangeModeCommand class which inherits from Command class. It allows the user switch between 2 sets of command for either addressbook or taskmanager.

Suppose the user has just executed the ChangeMode using:

switch addressbook(ab) or taskmanager(tm).

In any command mode, the execute() function of the LogicManager class is first called, which calls Model.getCommandMode() to check the current command mode and goes on to pass the command string and command mode string into the parseCommand() function of the AddressBookParser class. This, in turn, determines that the ChangeModeCommand feature is being evoked and calls the ChangeModeCommandParser to parse the string and compare with the current set of command: addressbook(ab) or taskmanager(tm). After validating the input with command mode prefix, ChangeModeCommand(input) is created and calles the excute() feature in ChangeModeCommand which then call Model.changeCommandMode(input) to change the current command mode and return a CommandResult object.

A diagram is shown below to illustrate this mechanism.

ChangeModeDiagram

End of Extract


Enhancement Added: find task

External behavior


Start of Extract [from: User Guide]

Finding tasks by description or deadline: find

Want to find a task? The find feature allows you to find task(s) by descriptions or deadlines.

To find task(s) whose descriptions contain any of the given keywords, use
Format: find KEYWORD [MORE_KEYWORDS]

To find task(s) by deadlines, use

Format: find DD-MM-YYYY

Examples:

  • find finish
    Returns finish task tonight and finish task tomorrow

  • find finish task tonight
    Returns any task(s) having a description containing finish, task, or tonight

  • find 29-10-2017
    Returns any task(s) having deadlines on 29-10-2017

Constraints:

Note the following constraints when finding tasks:

  • The search is case insensitive. e.g finish will match Finish.

  • The order of the keywords does not matter. e.g. Finish task will match task finish.

  • Only the description and deadline are searched.

  • Only full words will be matched e.g Finish will not match Finished.

  • Only valid dates will be matched e.g 291017 will not match 29-10-2017.

End of Extract


Justification

With many tasks to the application, it is hard to browse through each task to find the target task

Hence, with find task feature, user can easily search for the target task

Implementation


Start of Extract [from: Developer Guide]

FindTask mechanism

The FindTask mechanism is facilitated by the FindTaskCommand class which inherits from Command class. It allows the user to find tasks using descriptions. User can search using multiple descriptions too.

Suppose the user has just executed the FindTaskCommand using:

`find finish cs2103 17-07-1995`.

At first, the execute() function of the LogicManager class is called, which goes on to pass the command string into the parseCommand() function of the AddressBookParser class. This, in turn, determines that the FindTaskCommand feature is being evoked and calls the FindTaskCommandParser to parse the string and compare the descriptions. These are validated and formatted by the TaskContainsKeywordsPredicate and return as a TaskContainsKeywordsPredicate object to be used to call the FindTaskCommand class. The LogicManager then calls the execute() in the FindTaskCommand class which creates and return a CommandResult object.

public class TaskContainsKeywordsPredicate implements Predicate<ReadOnlyTask> {
    private final List<String> keywords;

    public TaskContainsKeywordsPredicate(List<String> keywords) {
        this.keywords = keywords;
    }

    @Override
    public boolean test(ReadOnlyTask task) {
        String testDate = "";
        String tag = Arrays.toString(task.getTags().toArray())
                .replaceAll("[\\[\\](),{}]", "");

        if (!task.getDeadline().isEmpty()) {
            try {
                Date date = ParserUtil.parseDate(task.getDeadline().date);
                DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
                testDate = dateFormat.format(date);
            } catch (IllegalValueException e) {
                e.printStackTrace();
            }
        }
        String finalTestDate = testDate;
        return keywords.stream()
                .anyMatch(keyword -> StringUtil.containsWordIgnoreCase(task.getDescription().taskDescription, keyword)
                || StringUtil.containsWordIgnoreCase(finalTestDate, keyword)
                || StringUtil.containsWordIgnoreCase(tag, keyword));
    }

Design Considerations

Aspect: Implementation of FindTaskCommand
Alternative 1 (current choice): Use String Util.containsword() to find tasks.
Pros: Easy to find matching descriptions among all the tasks accurately.
Cons: The keywords have to be exactly the save i.e friend is not the same as friends.
Alternative 2: Use string.contains() to find tasks.
Pros: Keywords do not have to be exactly the same as those in the description of tasks.
Cons: The search result might not be accurate. For e.g. if the user searches using the keyword 'a' all the tasks’descriptions that contains the character 'a' will appear.

End of Extract


Enhancement Added: select task

External behavior


Start of Extract [from: User Guide]

Selecting a task: select

You can use the select command to select the task identified by the index number used in the last task listing. Format: select INDEX

All contacts involved in the selected task will be listed. There will be no changes in the displayed list of contacks if there are no involved personnel.

Examples:

  • list
    select 2
    Selects the 2nd task in the task manager.

  • find finish
    select 1
    Selects the 1st task in the results of the find command. <*result list>

Constraints:

  • Selects the task at the specified INDEX.

  • The index refers to the index number shown in the most recent listing.

  • The index must be a positive integer 1, 2, 3, …​

End of Extract


Justification

The task tag feature allows user to include contacts that are involved in the task.

Hence, with the select task feature, when user selects the task select task feature will auto search for the contacts who are involved in the task.

Implementation


Start of Extract [from: Developer Guide]

SelectTask mechanism

The SelectTask mechanism is facilitated by the SelectTaskCommand class which inherits from Command class. It allows the user to select the task at specific index.

Suppose the user has just executed the SelectTaskCommand using:

`select 2`

At first, the execute() function of the LogicManager class is called, which goes on to pass the command string into the parseCommand() function of the AddressBookParser class. This, in turn, determines that the SelectTaskCommand feature is being evoked and calls the SelectTaskCommandParser to parse the string and check if the index is valid. After validation the SelectTaskCommand class is been called. SelectTaskCommand will then paraphrase the tag of selected task and pass it through conductSearch. conductSearch will call model.updateFilteredPersonList() with PersonContainsKeywordsPredicate with keyword tag as parameter to find the tag among person list and update person list. If there are no match found, all person will be listed. Then LogicManager then calls the execute() in the SelectTaskCommand class which calls EventCenter with the parameter of JumpToTaskListRequestEvent class to highlight selected task card in Ui at target index. Then execute() creates and return a CommandResult object.

End of Extract


Enhancement Added: list task

External behavior


Start of Extract [from: User Guide]

Listing tasks : list

You can use the list command to go back to the default list of tasks after a search.

Format: list

End of Extract


Justification

After user conduct a search for task, the user the user can view back the whole task list with list feature.

Implementation


Start of Extract [from: Developer Guide]

ListTask mechanism

The ListTask mechanism is facilitated by the ListTaskCommand class which inherits from Command class. It allows the user to list out all the current tasks.

Suppose the user has just executed the ListTaskCommand using:

`list`.

At first, the execute() function of the LogicManager class is called, which goes on to pass the command string into the parseCommand() function of the AddressBookParser class. This, in turn, determines that the ListTaskCommand feature is being evoked and calls the execute() in the ListTaskCommand class which update the current list to show all tasks creates and return a CommandResult object.

End of Extract


Possible idea

One possible idea is to include notification for task deadline. User will be notified if the deadline is on the day itself. Notification will be shown when user opens Mobilize.

This feature can remind the user about the task deadline.


Other contributions

  • Updated the GUI for command mode(Pull request #114)

  • Updated the GUI for task tags(Pull request #100)

  • Updated the GUI for task manager(Pull request #60)

  • Added some GUI test files for the team to conduct system tests(Pull request #60)