diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 085c5bdbe16c..5855eb14da9f 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -1,4 +1,8 @@ -# Developer Guide +# Developer Guide + + +  + ## Table of contents @@ -15,67 +19,78 @@ * [Appendix E : Product Survey](#appendix-e--product-survey) +  + + ## Introduction -Agendum is a task manager for the user to manage their schedules and todo tasks via keyboard commands. It is a Java desktop application that has a **GUI** implemented with JavaFX. +Agendum is a task manager for busy users to manage their schedules and tasks via keyboard commands. It is a Java desktop application that has a **GUI** implemented with JavaFX. + +This guide describes the design and implementation of Agendum. It will help developers (like you) understand how Agendum works and how to further contribute to its development. We have organized this guide in a top-down manner so that you can understand the big picture before moving on to the more detailed sections. Each sub-section is mostly self-contained to provide ease of reference. -This guide describes the design and implementation of Agendum. It will help developers understand how Agendum works and how they can further contribute to its development. We have organised this guide in a top-down manner so that you can understand the big picture before moving on to the more detailed sections. ## Setting up -#### 1. Prerequisites +### Prerequisites + +* **JDK `1.8.0_60`** or above
-* **JDK `1.8.0_60`** or later
+ > This application will not work with any earlier versions of Java 8. - > Having any Java 8 version is not enough.
- This application will not work with earlier versions of Java 8. - * **Eclipse** IDE * **e(fx)clipse** plugin for Eclipse (Do the steps 2 onwards given in [this page](http://www.eclipse.org/efxclipse/install.html#for-the-ambitious)) - -* **Buildship Gradle Integration** plugin from the + +* **Buildship Gradle Integration** plugin from the [Eclipse Marketplace](https://marketplace.eclipse.org/content/buildship-gradle-integration) -#### 2. Importing the project into Eclipse +### Importing the project into Eclipse + +1. Fork this repo, and clone the fork to your computer + +2. Open Eclipse (Note: Ensure you have installed the **e(fx)clipse** and **buildship** plugins as given in the prerequisites above) + +3. Click `File` > `Import` -* Fork this repo, and clone the fork to your computer -* Open Eclipse (Note: Ensure you have installed the **e(fx)clipse** and **buildship** plugins as given - in the prerequisites above) -* Click `File` > `Import` -* Click `Gradle` > `Gradle Project` > `Next` > `Next` -* Click `Browse`, then locate the project's directory -* Click `Finish` +4. Click `Gradle` > `Gradle Project` > `Next` > `Next` + +5. Click `Browse`, then locate the project's directory + +6. Click `Finish` > * If you are asked whether to 'keep' or 'overwrite' config files, choose to 'keep'. > * Depending on your connection speed and server load, it can even take up to 30 minutes for the set up to finish - (This is because Gradle downloads library files from servers during the project set up process) - > * If Eclipse auto-changed any settings files during the import process, you can discard those changes. - -#### 3. Troubleshooting project setup + (Gradle needs time to download library files from servers during the project set up process) + > * If Eclipse automatically changed any settings during the import process, you can discard those changes. + + > After you are done importing Agendum, it will be a good practice to enable assertions before developing. This will enable Agendum app to verify assumptions along the way. To enable assertions, follow the instructions [here](http://stackoverflow.com/questions/5509082/eclipse-enable-assertions) + +### Troubleshooting project setup * **Problem: Eclipse reports compile errors after new commits are pulled from Git** - * Reason: Eclipse fails to recognize new files that appeared due to the Git pull. - * Solution: Refresh the project in Eclipse:
- Right click on the project (in Eclipse package explorer), choose `Gradle` -> `Refresh Gradle Project`. - + * Reason: Eclipse fails to recognize new files that appeared due to the Git pull. + * Solution: Refresh the project in Eclipse:
+ * **Problem: Eclipse reports some required libraries missing** + * Reason: Required libraries may not have been downloaded during the project import. + * Solution: [Run tests using Gardle](UsingGradle.md) once (to refresh the libraries). + + +  - * Reason: Required libraries may not have been downloaded during the project import. - * Solution: [Run tests using Gardle](UsingGradle.md) once (to refresh the libraries). - ## Design ### 1. Architecture
+ The **_Architecture Diagram_** given above explains the high-level design of the App. Given below is a quick overview of each component. -`Main` has only one class called [`MainApp`](../src/main/java/seedu/agendum/MainApp.java). It is responsible for, +`Main` has only one class called [`MainApp`](../src/main/java/seedu/agendum/MainApp.java). It is responsible for the following: * At app launch: Initializes the components in the correct sequence, and connect them up with each other. * At shut down: Shuts down the components and invoke cleanup method where necessary. @@ -87,14 +102,14 @@ Two of those classes play important roles at the architecture level. is used by components to communicate with other components using events (i.e. a form of _Event Driven_ design) * `LogsCenter` : Used by many classes to write log messages to the App's log file. -The rest of the App consists four components. +The rest of the App comprises four components: -* [**`UI`**](#2-ui-component) : The UI of tha App. -* [**`Logic`**](#3-logic-component) : The command executor. -* [**`Model`**](#4-model-component) : Holds the data of the App in-memory. -* [**`Storage`**](#5-storage-component) : Reads data from, and writes data to, the hard disk. +* [**`UI`**](#2-ui-component) - The UI of the App. +* [**`Logic`**](#3-logic-component) - The command executor. +* [**`Model`**](#4-model-component) - Holds the data of the App in-memory. +* [**`Storage`**](#5-storage-component) - Reads data from, and writes data to, the hard disk. -Each of the four components +Each of the four components has the following properties: * Defines its _API_ in an `interface` with the same name as the Component. * Exposes its functionality using a `{Component Name}Manager` class. @@ -103,23 +118,24 @@ For example, the `Logic` component (see the class diagram given below) defines i interface and exposes its functionality using the `LogicManager.java` class.

-The _Sequence Diagram_ below shows how the components interact for the scenario where the user issues the -command `delete 1`. +The _Sequence Diagram_ below illustrates how the components interact for the scenario where the user issues the +command `delete 1` to delete the first task in the displayed list. The `UI` component will invoke the `Logic` component's _execute_ method to carry out the given command. In this scenario, the `Logic` component will identify the corresponding task and invoke `Model`'s _deleteTask(task)_ method to update the in-app memory and raise a `ToDoListChangedEvent`. >Note how the `Model` simply raises a `ToDoListChangedEvent` when the Agendum data are changed, - instead of asking the `Storage` to save the updates to the hard disk. + instead of directly asking the `Storage` to save the updates to the hard disk. + +The diagram below shows how the `EventsCenter` reacts to that raised event. The subscribers (the `UI` and `Storage` components) are informed and will respond accordingly. The status bar of the UI will be updated to reflect the 'Last Updated' time and the updates to the task data will also be saved to hard disk.
-The diagram below shows how the `EventsCenter` reacts to that event, which eventually results in the updates -being saved to the hard disk and the status bar of the UI being updated to reflect the 'Last Updated' time.
> Note how the event is propagated through the `EventsCenter` to the `Storage` and `UI` without `Model` having - to be coupled to either of them. This is an example of how this Event Driven approach helps us reduce direct + to be coupled to either of them. This application of Event Driven approach helps us reduce direct coupling between components. -The sections below give more details of each component. +The following sections will then give more details of each individual component. + ### 2. UI component @@ -128,20 +144,20 @@ The sections below give more details of each component. **API** : [`Ui.java`](../src/main/java/seedu/agendum/ui/Ui.java) The UI consists of a `MainWindow` that is made up of parts e.g.`CommandBox`, `ResultDisplay`, `TaskListPanel`, -`StatusBarFooter`, `BrowserPanel` etc. All these, including the `MainWindow`, inherit from the abstract `UiPart` class -and they can be loaded using the `UiPartLoader`. +`StatusBarFooter`, `BrowserPanel` etc. All these, including the `MainWindow`, inherit the abstract `UiPart` class. They can be loaded using `UiPartLoader`. The `UI` component uses JavaFx UI framework. The layout of these UI parts are defined in matching `.fxml` files that are in the `src/main/resources/view` folder.
For example, the layout of the [`MainWindow`](../src/main/java/seedu/agendum/ui/MainWindow.java) is specified in [`MainWindow.fxml`](../src/main/resources/view/MainWindow.fxml) -The `UI` component, +The `UI` component has the following functions: * Executes user commands using the `Logic` component. * Binds itself to some data in the `Model` so that the UI can auto-update when data in the `Model` change. * Responds to events raised from various parts of the App and updates the UI accordingly. + ### 3. Logic component
@@ -153,22 +169,49 @@ The `UI` component, 3. The command execution can affect the `Model` (e.g. adding a task) and/or raise events. 4. The result of the command execution is encapsulated as a `CommandResult` object which is passed back to the `Ui`. -Given below is the Sequence Diagram for interactions within the `Logic` component for the `execute("delete 1")` - API call.
+You can view the Sequence Diagram below for interactions within the `Logic` component for the `execute("delete 1")` API call.
+
+ ### 4. Model component +The structure and relationship of the various classes in the Model component is described in the diagram below.
+To modify the in-app data and retrieve the various task lists, other components such as Logic and UI will have to make use of the API provided by the model interface. **API** : [`Model.java`](../src/main/java/seedu/agendum/model/Model.java) -The `Model`, + +The `Model` has the following functions: * stores a `UserPref` object that represents the user's preferences. -* stores the Agendum data. -* exposes a `UnmodifiableObservableList` that can be 'observed' e.g. the UI can be bound to this list - so that the UI automatically updates when the data in the list change. -* does not depend on any of the other three components. +* stores and manages Agendum's task list data. +* exposes a `UnmodifiableObservableList` that can be 'observed' by other components e.g. the UI can be bound to this list + so that the UI will automatically update when the data in the list change. + +The `Model` component does not depend on any of the other three components and has the following classes and interfaces. + +#### `Model Manager` class +The `Model Manager` class implements the `Model` interface. When the in-memory model of the to-do list data is updated, a ToDoListChangedEvent will be raised. + +#### `User Pref` +This class represents user's preferences such as their preferences about `Gui Settings`. + +#### `ToDoList` +This class wraps all the data at the to-do list level. Currently, each `ToDoList` object has a single `UniqueTaskList`. In the future, this class can be extended to keep track of the tags associated with tasks (`UniqueTagList`) and sync the tasks and tags. + +#### `ReadOnlyToDoList` class +This interface provides an unmodifiable view of the internal to-do list. It will return a task list consisting of read-only tasks. + +#### `Unique Task List` class +This class represents a list of tasks. Each task must be unique and must not be null. It supports a minimal set of list operations such as adding a `Task` to the list and deleting or replacing a `Task` in the list. Exceptions will be raised if any of the list operations invoked violates the 'no duplicates' property of the list or when a target task cannot be found. + +#### `Task` class +This class represents a task in the Unique Task List. Each `Task` must have a name and a completion status. It is optional for a `Task` to have a start time and a end time. Accessor methods are also defined for other classes such as the `Model Manager` class to identify if a task is overdue, upcoming or incomplete. + +#### `ReadOnlyTask` interface +This interface allows other Objects to view the details of a `Task` but does not allow them to modify the details. For example, an unmodifiable observable list of read-only tasks will be shown on the UI. + ### 5. Storage component @@ -176,15 +219,70 @@ The `Model`, **API** : [`Storage.java`](../src/main/java/seedu/agendum/storage/Storage.java) -The `Storage` component, +The `Storage` component has the following functions: * can save `UserPref` objects in json format and read it back. * can save the Agendum data in xml format and read it back. + ### 6. Common classes Classes used by multiple components are in the `seedu.agendum.commons` package. +They are further separated into sub-packages - namely `core`, `events`, `exceptions` and `util`. + +#### Core +This package consists of the essential classes that are required by multiple components. + +* `ComponentManager` - This is a base class of manager classes, namely `LogicManager`, `ModelManager`, `StorageManager` and `UiManager` +* `Config` - This file stores the configuration values of Agendum; these include: + * Application title + * Logging level + * User preferences file path + * ToDoList data path +* `EventsCenter` - This class uses _Event Driven_ design. It manages all the events of the app. Whenever an event is raised, it will be dispatched to all the classes that have subscribed to this event. It is written using [Google's Event Bus library](https://github.com/google/guava/wiki/EventBusExplained) +* `GuiSettings` - This class saves the setting of the GUI, such as the width, height and coordinates on the screen. +* `LogsCenter` - Used by many classes to write log messages to the App's log file. +* `Messages` - Stores generalised messages that will be visible to the user. +* `UnmodifiableObservableList` - This class is a container of oberservable list, making it an unmodifiable obervable list +* `Version` - Stores some information about the version of the App + +#### Events +This package consists of the different type of events that can occur; these are used mainly by EventManager and EventBus. + +* `SaveLocationChangedEvent` - This event will be dispatched to the UI and Storage classes when the user uses the `store` command. +* `ToDoListChangedEvent` - This event will be dispatch to UI and Storage when the user mutates the todo list +* `DataSavingExceptionEvent` - This event indicates an exception during a file saving +* `ExitAppRequestEvent` - This event indicates the user has requested to exit the app. +* `IncorrectCommandAttemptedEvent` - This event represents an incorrect input by the user +* `JumpToListRequestEvent` - This event indicates a request to jump to the list of tasks +* `ShowHelpRequestEvent` - This event indicates user has used the help `command` +* `TaskPanelSelectionChangedEvent` - This event indicates the user has selected a different panel + +#### Exceptions +This package consists of exceptions that may occur with the use of Agendum. + +* `DataConversionException` - This exception is thrown when conversion from one data format to another has failed. +* `DuplicateDataException` - This exception is thrown when there are multiple occurrences of the same data, when it is not allowed. +* `FileDeletionException` - This exception is thrown when a valid file cannot be deleted. +* `IllegalValueException` - This exception is thrown when given data does not fulfil requirements, e.g. Only positive numbers allowed, but -1 is given + +#### Util +This package consists of additional utilities for the different components. +* `AppUtil` - Used for app specific functions, e.g. loading an image +* `CollectionUtil` - Used for checking or validating collections, e.g. ensure no null objects in a list +* `ConfigUtil` - Used for accessing the Config file, such as loading and saving +* `FileUtil` - Used for writing, reading and deleting files, as well as checking existence and validation +* `FxViewUtil` - Used for JavaFX views +* `JsonUtil` - Used for conversion between Java Objects and json files +* `StringUtil` - Used for additional functions in handling strings, such as checking if the string has only unsigned integers +* `UrlUtil` - Used for handling URLs to websites +* `XmlUtil` - Used for reading and writing XML files. + + +  + + ## Implementation ### 1. Logging @@ -196,97 +294,109 @@ and logging destinations. (See [Configuration](#2-configuration)) * The `Logger` for a class can be obtained using `LogsCenter.getLogger(Class)` which will log messages according to the specified logging level -* Currently log messages are output through: `Console` and to a `.log` file. +* Currently log messages are output through `Console` and to a `.log` file. **Logging Levels** -* `SEVERE` : Critical problem detected which may possibly cause the termination of the application -* `WARNING` : Can continue, but with caution -* `INFO` : Information showing the noteworthy actions by the App -* `FINE` : Details that is not usually noteworthy but may be useful in debugging - e.g. print the actual list instead of just its size +Currently, Agendum has 4 logging levels: `SEVERE`, `WARNING`, `INFO` and `FINE`. They record information pertaining to: + +* `SEVERE` : A critical problem which may cause the termination of Agendum
+ e.g. fatal error during the initialization of Agendum's main window +* `WARNING` : A problem which requires attention and caution but allows Agendum to continue working
+ e.g. error reading from/saving to config file +* `INFO` : Noteworthy actions by Agendum
+ e.g. valid and invalid commands executed and their results +* `FINE` : Less significant details that may be useful in debugging
+ e.g. print the elements in actual list instead of just its size ### 2. Configuration -Certain properties of the application can be controlled (e.g App name, logging level) through the configuration file +You can alter certain properties of our Agendum application (e.g. logging level) through the configuration file. (default: `config.json`): -## Testing +  -Tests can be found in the `./src/test/java` folder. +## Testing -**1. In Eclipse**: +You can find all the test files in the `./src/test/java` folder. -* To run all tests, right-click on the `src/test/java` folder and choose - `Run as` > `JUnit Test` -* To run a subset of tests, you can right-click on a test package, test class, or a test and choose - to run as a JUnit test. +### Types of Tests -**2. Using Gradle**: +#### 1. GUI Tests -* See [UsingGradle.md](UsingGradle.md) for how to run tests using Gradle. +These are _System Tests_ that test the entire App by simulating user actions on the GUI. +They are in the `guitests` package. -**3. Type of tests**: +#### 2. Non-GUI Tests -* **GUI Tests**
-These are _System Tests_ that test the entire App by simulating user actions on the GUI. They are in the `guitests` package. - -* **Non-GUI Tests**
These are tests not involving the GUI. They include, * _Unit tests_ targeting the lowest level methods/classes.
- e.g. `seedu.agendum.commons.UrlUtilTest` - * _Integration tests_ that are checking the integration of multiple code units + e.g. `seedu.agendum.commons.StringUtilTest` tests the correctness of StringUtil methods e.g. if a source string contains a query string, ignoring letter cases. + * _Integration tests_ that are checking the integration of multiple code units (those code units are assumed to be working).
- e.g. `seedu.agendum.storage.StorageManagerTest` - * Hybrids of _unit and integration tests_. These test are checking multiple code units as well as + e.g. `seedu.agendum.storage.StorageManagerTest` tests if StorageManager is correctly connected to other storage components such as JsonUserPrefsStorage. + * Hybrids of _unit and integration tests_. These tests are checking multiple code units as well as how the are connected together.
- e.g. `seedu.agendum.logic.LogicManagerTest` - -**4. Headless GUI Testing** : + e.g. `seedu.agendum.logic.LogicManagerTest` will check various code units from the `Model` and `Logic` components. + +#### 3. Headless Mode GUI Tests Thanks to the [TestFX](https://github.com/TestFX/TestFX) library we use, - our GUI tests can be run in the _headless_ mode. - In the headless mode, GUI tests do not show up on the screen. - That means the developer can do other things on the Computer while the tests are running.
- See [UsingGradle.md](UsingGradle.md#running-tests) to learn how to run tests in headless mode. - +our GUI tests can be run in [headless mode](#headless-mode).
+See [UsingGradle.md](UsingGradle.md#running-tests) for instructions on how to run tests in headless mode. + +### How to Test + +#### 1. Using Eclipse + +* To run all tests, right-click on the `src/test/java` folder and choose `Run as` > `JUnit Test` +* To run a subset of tests, you can right-click on a test package, test class, or a test and choose to run as a JUnit test. + +#### 2. Using Gradle + +* See [UsingGradle.md](UsingGradle.md) for how to run tests using Gradle. + >#### Troubleshooting tests >**Problem: Tests fail because NullPointException when AssertionError is expected** ->* Reason: Assertions are not enabled for JUnit tests. +>* Reason: Assertions are not enabled for JUnit tests. This can happen if you are not using a recent Eclipse version (i.e. _Neon_ or later) ->* Solution: Enable assertions in JUnit tests as described +>* Solution: Enable assertions in JUnit tests as described [here](http://stackoverflow.com/questions/2522897/eclipse-junit-ea-vm-option).
Delete run configurations created when you ran tests earlier. - + + +  + + ## Dev Ops ### 1. Build Automation -See [UsingGradle.md](UsingGradle.md) to learn how to use Gradle for build automation. +We use Gradle to run tests and manage library dependencies. The Gradle configuration for this project is defined in _build.gradle_. Refer to [UsingGradle.md](UsingGradle.md) for more instructions on how to use Gradle for build automation. ### 2. Continuous Integration -We use [Travis CI](https://travis-ci.org/) to perform _Continuous Integration_ on our projects. -See [UsingTravis.md](UsingTravis.md) for more details. +We use [Travis CI](https://travis-ci.org/) to perform _Continuous Integration_ on our project. When code is pushed to this repository, Travis CI will run the project tests automatically to ensure that existing functionality will not be negatively affected by the changes. +Refer to [UsingTravis.md](UsingTravis.md) for more details. ### 3. Making a Release -Here are the steps to create a new release. - +To contribute a new release: + 1. Generate a JAR file [using Gradle](UsingGradle.md#creating-the-jar-file). - 2. Tag the repo with the version number. e.g. `v0.1` - 2. [Create a new release using GitHub](https://help.github.com/articles/creating-releases/) - and upload the JAR file your created. - + 2. Tag the repo with the version number. e.g. `v1.1` + 2. [Create a new release using GitHub](https://help.github.com/articles/creating-releases/) + and upload the JAR file you created. + ### 4. Managing Dependencies -A project often depends on third-party libraries. For example, Agendum depends on the -[Jackson library](http://wiki.fasterxml.com/JacksonHome) for XML parsing. Managing these dependencies can be automated using Gradle. For example, Gradle can download the dependencies automatically, which is better than these alternatives: +Agendum depends on third-party libraries, such as the +[Jackson library](http://wiki.fasterxml.com/JacksonHome) for XML parsing. Managing these dependencies have been automated using Gradle. Gradle can download the dependencies automatically hence the libraries are not included in this repo and you do not need to download these libraries manually. To add a new dependency, update _build.gradle_. + -* Include those libraries in the repo -* Require developers to download those libraries manually +  ## Appendix A : User Stories @@ -312,7 +422,7 @@ Priority | As a ... | I want to ... | So that I can... `* * *` | Busy User | Edit and remove start and end time of tasks | Update events with defined start and end dates `* * *` | Busy User | Edit and remove deadlines of tasks | Update tasks which must be done by a certain and date and time `* *` | User | Sort tasks by alphabetical order and date | Organise and easily locate tasks -`* *` | User | Filter upcoming and overdue tasks | Decide on what needs to be done soon +`* *` | User | Filter overdue tasks and upcoming tasks (due within a week) | Decide on what needs to be done soon `* *` | User | Filter tasks based on whether they are marked/unmarked | View my tasks grouped by their state of completion. Review my completed tasks and decide on what I should do next `* *` | User | See the count/statistics for upcoming/ overdue and pending tasks | Know how many tasks I need to do `*` | User | Clear the command I am typing with a key | Enter a new command without having to backspace the entire command line @@ -334,6 +444,9 @@ Priority | As a ... | I want to ... | So that I can... `* Unlikely` | Busy user | Can specify a priority of a task | Keep track of what tasks are more important +  + + ## Appendix B : Use Cases >For all use cases below, the **System** is `Agendum` and the **Actor** is the `user`, unless specified otherwise @@ -342,22 +455,22 @@ Priority | As a ... | I want to ... | So that I can... **MSS** -1. System prompts the user to enter a command -2. User enters an add command with the task name into the input box. +1. System prompts the Actor to enter a command +2. Actor enters an add command with the task name into the input box. 3. System adds the task. -4. System shows a feedback message (“Task added”) and displays the updated list containing the new task on the interface. +4. System shows a feedback message ("Task `name` added") and displays the updated list 5. Use case ends. **Extensions** 2a. No task description is provided -> 2a1. System shows an error message (“Please provide a task name/description”) +> 2a1. System shows an error message (“Please provide a task name/description”)
> Use case resumes at step 1 2b. There is an existing task with the same description and details -> 2b1. System shows an error message (“Please use a new task description”) +> 2b1. System shows an error message (“Please use a new task description”)
> Use case resumes at step 1 ### Use case 02 - Delete a task @@ -368,7 +481,7 @@ Priority | As a ... | I want to ... | So that I can... 2. System shows a list of tasks 3. Actor requests to delete a specific task in the list by its index 4. System deletes the task. -5. System shows a feedback message (“Task deleted”) and displays the updated list without the deleted task. +5. System shows a feedback message (“Task `index` deleted”) and displays the updated list 6. Use case ends. **Extensions** @@ -379,7 +492,7 @@ Priority | As a ... | I want to ... | So that I can... 3a. The given index is invalid -> 3a1. System shows an error message (“Please select a task on the list with a valid index”) +> 3a1. System shows an error message (“Please select a task on the list with a valid index”)
> Use case resumes at step 2 ### Use case 03 - Rename a task @@ -389,8 +502,8 @@ Priority | As a ... | I want to ... | So that I can... 1. Actor requests to list tasks 2. System shows a list of tasks 3. Actor requests to rename a specific task in the list by its index and also input the new task name -4. System updates the task -5. System shows a feedback message (“Task updated”) and displays the updated list with the edited task name. +4. System updates the task +5. System shows a feedback message (“Task `index` updated”) and displays the updated list 6. Use case ends. **Extensions** @@ -401,28 +514,28 @@ Priority | As a ... | I want to ... | So that I can... 3a. The given index is invalid -> 3a1. System shows an error message (“Please select a task on the list with a valid index”) +> 3a1. System shows an error message (“Please select a task on the list with a valid index”)
> Use case resumes at step 2 3b. No task description is provided -> 3b1. System shows an error message (“Please include a new task name”) +> 3b1. System shows an error message (“Please include a new task name”)
> Use case resumes at step 2 3c. There is an existing task with the same description and details -> 3c1. System shows an error message (“Please use a new task name”) +> 3c1. System shows an error message (“Please use a new task name”)
> Use case resumes at step 2 -### Use case 04 - Modify a task’s start and end time and deadlines +### Use case 04 - Schedule a task’s start and end time and deadlines **MSS** 1. Actor requests to list tasks 2. System shows a list of tasks -3. Actor requests to set time of a specific task in the list by its index and also input the new start/end time or deadline -4. System updates the task -5. System shows a feedback message (“Task ’s time updated”) and displays the updated list on the interface. +3. Actor inputs index and the new start/end time or deadline of the task to be modified +4. System updates the task +5. System shows a feedback message (“Task `index`'s time/date has been updated”) and displays the updated list 6. Use case ends. **Extensions** @@ -433,29 +546,29 @@ Priority | As a ... | I want to ... | So that I can... 3a. The given index is invalid -> 3a1. System shows an error message (“Please select a task on the list with a valid index”) +> 3a1. System shows an error message (“Please select a task on the list with a valid index”)
> Use case resumes at step 2 3b. The new input time format is invalid -> 3b1. System shows an error message (“Please follow the given time format”) +> 3b1. System shows an error message (“Please follow the given time format”)
> Use case resumes at step 2 -### Use case 05 - Undo the previous command that modified the task list +### Use case 05 - Undo previous command that modified the task list **MSS** -1. Actor enters an undo command +1. Actor enters the undo command 2. System finds the latest command that modified the task list 3. System undo the identified command -4. System shows a feedback message (“The command has been undone”) and displays the updated list on the interface. +4. System shows a feedback message (“The command `last-command` has been undone”) and displays the updated list. 5. Use case ends. **Extensions** 2a. There are no previous commands that modify the list (since the launch of the application) -> 2a1. System shows an error message (“No previous command to undo”) +> 2a1. System shows an error message (“No previous command to undo”)
> Use case ends ### Use case 06 - Mark a task as completed @@ -466,7 +579,7 @@ Priority | As a ... | I want to ... | So that I can... 2. System show a list of tasks 3. Actor requests to mark a task specified by its index in the list as completed 4. System updates the task -5. System shows a feedback message (“Task is marked as completed”) and hides the marked task. +5. System shows a feedback message (“Task `index` is marked as completed”) and hides the marked task. 6. Use case ends **Extensions** @@ -477,7 +590,7 @@ Priority | As a ... | I want to ... | So that I can... 3a. The given index is invalid -> 3a1. System shows an error message (“Please select a task on the list with a valid index”) +> 3a1. System shows an error message (“Please select a task on the list with a valid index”)
> Use case resumes at step 2 ### Use case 07 - Add short hand commands @@ -486,64 +599,133 @@ Priority | As a ... | I want to ... | So that I can... 1. Actor enters a alias command and specify the name and new alias name of the command 2. System alias the command -3. System shows a feedback message (“The command can now be keyed in as ”) +3. System shows a feedback message (“The command `original-command` can now be keyed in as ”) 4. Use case ends. **Extensions** 1a. There is no existing command with the original name specified -> 1a1. System shows an error message (“There is no such existing command”) +> 1a1. System shows an error message (“There is no such existing command”)
> Use case ends 1b. The new alias name is already reserved/used for other commands -> 1b1. System shows an error message (“The name is already in use”) +> 1b1. System shows an error message (“The name is already in use”)
> Use case ends *a. At any time, Actor choose to exit System -> *a1. System displays a goodbye message +> *a1. System displays a goodbye message
> *a2. System closes the program *b. At any time, Actor enters a invalid command -> *b1. System gives an error message (“We do not understand the command: ”) +> *b1. System gives an error message (“We do not understand the command: `invalid-command`”)
> *b2. System displays a short list of valid commands +### Use case 08 - Specify data storage location + +**MSS** + +1. Actor enters store command followed by a path to file +2. System updates data storage location to the specified path to file +3. System shows a feedback message ("New save location: `path-to-file`") +4. Use case ends. + +**Extensions** + +1a. Path to file is input as 'default' + +> 1a1. System updates data storage location to default
+> 1a2. System shows a feedback message ("Save location set to default: `path-to-file`")
+> Use case ends + +1b. File exists +> 1b1. System shows an error message ("The specified file exists; would you like to use LOAD instead?")
+> Use case ends + +1c. Path to file is invalid + +> 1c1. System shows an error message ("The specified path to file is invalid.")
+> Use case ends + + + +### Use case 09 - Load from data file + +**MSS** + +1. Actor enters load command followed by a path to file +2. System saves current task list into existing data storage location +3. System loads task list from specified path to file +2. System updates data storage location to the specified path to file +3. System shows a feedback message ("Data successfully loaded from: `path-to-file`") +4. Use case ends. + +**Extensions** + +1a. Path to file is invalid + +> 1a1. System shows an error message ("The specified path to file is invalid.")
+> Use case ends + +3a. File is in the wrong format + +> 3a1. System shows an error message ("File is in the wrong format.")
+> Use case ends + + +  + + ## Appendix C : Non Functional Requirements 1. Should work on any [mainstream OS](#mainstream-os) as long as it has Java `1.8.0_60` or higher installed. -2. Should be able to hold up to 500 tasks. +2. Should be able to hold up to 800 tasks in total (including completed tasks). 3. Should come with automated unit tests. 4. Should use a Continuous Integration server for real time status of master’s health. 5. Should be kept open source code. 6. Should favour DOS style commands over Unix-style commands. -7. Should be able to accept minor mistakes in the commands entered. -8. Should adopt an object oriented design. -9. Should not violate any copyrights. -10. Should have a response time of less than 1 second, for every action performed. -11. Should work offline without an internet connection. -12. Should work as a standalone application. -13. Should not use relational databases to store data. -14. Should store data in an editable text file. -15. Should not require an installer. -16. Should not use paid libraries and frameworks. +7. Should adopt an object oriented design. +8. Should not violate any copyrights. +9. Should have a response time of less than 1 second, for every action performed. +10. Should work offline without an internet connection. +11. Should work as a standalone application. +12. Should not use relational databases to store data. +13. Should store data in an editable text file. +14. Should not require an installer. +15. Should not use paid libraries and frameworks. + + +  + ## Appendix D : Glossary -##### Mainstream OS: +##### Mainstream OS: Windows, Linux, Unix, OS-X +##### Headless Mode: + +In the headless mode, GUI tests do not show up on the screen.
+This means you can do other things on the Computer while the tests are running. + + +  + + ## Appendix E : Product Survey +We conducted a product survey on other task managers. Here is a summary of the strengths and weaknesses of each application. The criteria used for evaluation are own preferences and Jim's requirements. + #### Wunderlist *Strengths:* -* Clearly display tasks that have not been completed +* Clearly displays tasks that have not been completed * Tasks can be categorized under different lists * Tasks can have sub tasks * Possible to highlight tasks by marking as important (starred) or pinning tasks @@ -559,4 +741,25 @@ Windows, Linux, Unix, OS-X *Weaknesses:* * Wunderlist has a complex interface and might require multiple clicks to get specific tasks done. For example, it has separate field to add tasks, search for tasks and a sort button. There are various lists & sub-lists. Each list has a completed/uncompleted section and each task needs to be clicked to display the associated subtasks, notes, files and comment. -* New users might not know how to use the advanced features e.g. creating recurring tasks \ No newline at end of file +* New users might not know how to use the advanced features e.g. creating recurring tasks + +#### Google calendar + +*Strengths:* + +* Have a weekly/monthly/daily calendar view which will make it easy for users to visualize their schedules +* Can create recurring events +* Integrated with Gmail. A user can add events from emails easily and this is desirable since Jim's to do items arrive by emails +* Can be used offline +* Possible to synchronize across devices +* Calendar can be exported to CSV/iCal for other users +* CLI to quick add an event to a calendar instead of clicking through the screen +* Comprehensive search by name/details/people involved/location/time + + +*Weaknesses:* + +* Not possible to mark tasks as completed +* Not possible to add tasks without deadline or time +* CLI does not support updating of tasks/deleting etc. Still requires clicking. +* New users might not know of the keyboard shortcuts diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 748dbafb90dd..dca8d7e1a921 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -8,45 +8,50 @@ ## Quick Start -0. Ensure you have Java version `1.8.0_60` or later installed in your Computer. +0. Ensure you have Java version `1.8.0_60` or above installed in your Computer. - > Agendum will not work with earlier versions of Java 8. + > Take note that Agendum might not work with earlier versions of Java 8. 1. Download the latest `Agendum.jar` from the [releases](../../../releases) tab. -2. Copy the file to the folder you want to use as the home folder for Agendum. +2. Copy Agendum.jar to the folder you want to use as the home. -3. Double-click the file to start Agendum. The GUI should appear in a few seconds. +3. Double-click the file to start Agendum. The GUI should appear promptly. 4. Type a command in the command box and press Enter to execute it. e.g. typing **`help`** and pressing Enter will list some information about commands. - -5. Here are some commands you can try: + +5. Go ahead and try some of the commands listed below! * **`add`**` Go to shopping mall` : adds a task with description `Go to shopping mall` to Agendum. * **`delete`**` 3` : deletes the 3rd task shown in the current list - * **`list`** : lists all tasks + * **`list`** : lists all uncompleted tasks * **`exit`** : exits Agendum -6. Refer to the [Features](#features) section below for more details of each command. +6. You can refer to the [Features](#features) section below for more details of each command. +   + ## Features > **Command Format** > * Words in `UPPER_CASE` are the parameters. -> * Items in `SQUARE_BRACKETS` are optional. -> * Items with `...` after them can have multiple instances. +> * Parameters in `SQUARE_BRACKETS` are optional. +> * Parameters with `...` after them can have multiple instances. > * The order of parameters is fixed. -> * Commands are not case-sensitive e.g `list` will match `List` +> * Commands and parameters are not case-sensitive e.g `list` will match `List` + #### Viewing help : `help` -If you need some more information about the features available, you can use the `help` command.
-Format: `help` +If you need some reminder or more information about the features available, you can use the `help` command. + +Format: `help` > Help is also shown if an incorrect command is entered e.g. `run` + #### Adding a task: `add` You can add a task without a specific time and date.
@@ -58,8 +63,8 @@ Examples: * `add Workout` * `add watch Star Wars` -If you need a task to be done by a specific date, you can specify it using `by` or `before`.
-Format: `add TASK_NAME [by DATE_TIME]` or `add TASK_NAME [before DATE_TIME]` +If you need a task to be done by a specific date, you can specify the deadline after the keyword `by`.
+Format: `add TASK_NAME [by DATE_TIME]` > Date formats are not case-sensitive Examples: @@ -69,43 +74,45 @@ Examples: * `add watch Star Wars by next Wed` * `add watch Star Wars by 10 Oct, 9.30pm` -If you need a task to be done within a specific date and time, you can specify it using `from` and `to`.
-Format: `add TASK_NAME [from START_DATE_TIME] [to END_DATE_TIME] ` +If you need a task to be done within a specific date and time, you can specify the start and end time using `from` and `to`.
+Format: `add TASK_NAME [from START_DATE_TIME to END_DATE_TIME] ` > If you specify the time but no day or date is given, the date of creation will be used. Examples: -* `add watch Star Wars from 7pm` * `add movie marathon from today 12pm to friday 3pm` -* `add project meeting from 10 oct 12pm to 2pm` - -The event “watch Star Wars” will begin at 7pm on the date of creation. No end time will be attached to the task. +* `add project meeting from 10 oct 12pm to 10 oct 2pm` The event “project meeting” will start at 12pm on 10 October and end at 2pm on 10 October. #### Retrieving task list : `list` -You can see tasks sorted by date. Tasks without a date will be appended at the end of the list. +You can view tasks sorted by date. Tasks without a date will be appended at the end of the list.
+Format: `list [TYPE]` +> `TYPE` refers to a keyword such as `overdue, near, done or all`. -You can view a list of all uncompleted tasks.
-Format: `list` +Examples: + +* `list`
+ Agendum will show you a list of all uncompleted tasks. -You can view a list of overdue tasks.
-Format: `list overdue` +* `list overdue`
+ Agendum will show you a list of overdue tasks. -You can view a list of upcoming tasks within a week.
-Format: `list near` +* `list near`
+ Agendum will show you a list of upcoming tasks within a week.
-You can view a list of completed tasks.
-Format: `list done` +* `list done`
+ Agendum will show you a list of completed tasks.
+ +* `list all`
+ Agendum will show you a list of all tasks including overdue, completed and uncompleted tasks.
-You can view a list of all tasks, which includes overdue, completed and uncompleted tasks.
-Format: `list all` #### Finding tasks containing keywords: `find` -If you have a huge list of tasks and need to find only specific ones, you can use this command to search for tasks which contain any of the given keywords.
+If you have a long list of tasks and need to find only specific ones, you can use this command to search for tasks which contain any of the given keywords.
Format: `find KEYWORD``...` > * The search is not case sensitive. e.g `assignment` will match `Assignment` @@ -118,13 +125,14 @@ Examples: * `find Dory`
Returns `Shark & Dory` and `dory` - + * `find Nemo Dory`
Returns all tasks that contain `Dory` or `Nemo` + #### Deleting a task : `delete` -You can delete tasks that are no longer required.
+You can delete tasks that you no longer want to keep track of.
Format: `delete INDEX...` > * Deletes the task at the specified `INDEX`. @@ -136,7 +144,7 @@ Examples: * `list`
`delete 2`
Deletes the 2nd task in the task list. - + * `find movie`
`delete 1`
Deletes the 1st task in the results of the `find` command. @@ -147,14 +155,17 @@ Examples: * `list`
`delete 2 3 4`
- Deletes the 2nd, 3rd and 4th task in the task list. + `delete 2,3,4`
+ `delete 2-4`
+ Each of the above command will delete the 2nd, 3rd and 4th task in the task list. + #### Renaming a task : `rename` -If you find that the name of a task is not suitable, you can rename it.
+If you find that the name of an existing task is not suitable, you can always rename it.
Format: `rename INDEX NEW_TASK_NAME` -> * Renames the task at the specified `INDEX`. +> * Renames the task at the specified `INDEX`. > * Index refers to the index number shown in the most recent listing. > * The index **must be a positive integer** 1, 2, 3, ... @@ -163,17 +174,18 @@ Examples: * `list`
`rename 2 Star Wars II`
Renames the 2nd task in the list to “Star Wars II” - + * `find Star Trek`
`rename 1 Star Wars II`
Renames the 1st task in the results of the `find` command to “Star Wars II” + #### Updating the date/time of a task : `schedule` -If your deadline has been reduced or extended and you need to change the date of time of a task, you can use this command.
-Format: `schedule INDEX [NEW_DATE_TIME]` +Have the deadline of your task been reduced or extended? Have an event been rescheduled? To change the date or time of a task, you can use this command.
+Format: `schedule INDEX [NEW_DATE_TIME_RESTRICTIONS]` -> * Schedule the task at the specified `INDEX`. +> * Schedule 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, ... > * The time description must follow the format given in the add command examples @@ -182,19 +194,20 @@ Examples: * `list`
`schedule 4`
- Removes the start and end date/time or deadline for task 4 on the list. - + Removes the deadline and start and end date/time for task 4 on the list. + * `list`
`schedule 2 by Fri`
- Removes the start and end date/time or deadline for task 2 and sets the deadline to the coming Friday (If the current day is Friday, it would be the following Friday). - + Removes the deadline and start and end date/time for task 2 and resets the deadline to the coming Friday (If the current day is Friday, it would be the following Friday). + * `list`
- `schedule 3 from 1 Oct 7pm to 9.30pm`
- Sets task 3 to start on 1 Oct at 7pm and end at 9.30pm + `schedule 3 from 1 Oct 7pm to 1 Oct 9.30pm`
+ Sets the start time of task 3 to 1 Oct 7pm and the end time to 1 Oct 9.30pm respectively + #### Marking a task as completed : `mark` -If you have completed a task, you can mark it as completed by using this command.
+If you have completed a task, you can mark it as completed by using the following command.
Format: `mark INDEX...` > * Mark the task at the specified `INDEX`. @@ -207,7 +220,7 @@ Examples: * `list`
`mark 2`
Marks the 2nd task in the list. - + * `find Homework`
`mark 1`
Marks the 1st task in the list of results of the `find` command. @@ -218,13 +231,16 @@ Examples: * `list`
`mark 2 3 4`
- Marks the 2nd, 3rd and 4th task in the task list. + `mark 2,3,4`
+ `mark 2-4`
+ Each of the above command will mark the 2nd, 3rd and 4th task as completed. + #### Unmarking a task as completed : `unmark` -If a certain task still has work remaining, you can remove the marking.
-This works simlar to the `mark` command.
+You might change your mind and want to continue working on a completed task. To reflect these changes in Agendum, follow this command:
Format: `unmark INDEX...` +This works in a same way as the `mark` command.
#### Undo the last command : `undo` @@ -239,7 +255,8 @@ Examples: `undo`
The task "homework" which has been added previously, will be removed. -#### Create an alias for a command : `alias` + +#### Creating an alias for a command : `alias` If you are looking for alternatives or want to type a command faster, you can use the `alias` comand.
You can use both new and old command aliases to carry out the same action.
@@ -247,17 +264,17 @@ Format: `alias ORIGINAL_COMMAND_NAME NEW_COMMAND_NAME` > * NEW_COMMAND_NAME must be a single word. > * ORIGINAL_COMMAND_NAME must be a command word that is specified in the Command Summary section -> * Only one alias can be used -> * When creating a new alias with a pre-existing alias, the previous alias will be overriden. +> * When creating an alias for a command with a pre-existing alias, the pre-existing alias will be overriden. Examples: * `alias mark m`
- `m` and `mark` can now be used to mark a task.
+ you can now use`m` or `mark` to mark a task as completed.
`alias mark mk`
- only `mk` and `mark` can be used to mark a task, as `m` has been overriden. + Now you can only use `mk` or `mark` to mark a task; `m` has been overriden. + -#### Remove an alias command : `unalias` +#### Removing an alias command : `unalias` If you no longer want to use the alternative alias command, you can remove it. Format: `unalias NEW_COMMAND_NAME` or `unalias ORIGINAL_COMMAND_NAME` @@ -270,62 +287,93 @@ Examples: * `unalias m`
`m` can no longer be used to mark tasks.
`unalias mark`
- The assigned alias for `mark` will be removed, and only `mark` can be used to mark a task as completed. + The assigned alias for `mark` will be removed; Now you can only use the original command `mark` to mark a task as completed. -#### Specifying a data storage location : `store` -If you want to store the task list data in a different location, you can specifiy it using this command.
-Format: `store FILE_PATH` +#### Specifying the data storage location : `store` -> FILE_PATH must be a valid path on the local computer -> If a file at FILE_PATH exists, it will be overriden. +If you want to store the task list data in a different location, you can specifiy it using this command. +The task list data will be moved to the specific directory, and future data will be saved in that location.
+Format: `store PATH_TO_FILE` + +> * PATH_TO_FILE must be a valid path to a file on the local computer. +> * If a file at PATH_TO_FILE exists, it will be overriden. +> * The previous data storage file will not be deleted. Examples: -* `store C:/Dropbox/ToDo` +* `store C:/Dropbox/ToDo/mytasklist.xml` + + +#### Loading from another data storage location : `load` -The task list data will be moved to the specific directory, and future data will be saved in that location. +If you have another data file with existing task data, you can load it into Agendum.

+Format: `load PATH_TO_FILE` + +> * PATH_TO_FILE must be a valid path to a file on the local computer. +> * Existing data will be saved and stored in the existing data storage location. +> * The task list in Agendum will be replaced by the loaded task list. +> * Future data will be stored in PATH_TO_FILE. + +Examples: +* `load data/mytasklist.xml` #### Exiting the program : `exit` If you have finished using the application, you can use this command to exit the program.
Format: `exit` + #### Keyboard Shortcuts 1. Use the UP ARROW and DOWN ARROW to scroll through earlier commands. -2. If you are entering a command, use the DOWN ARROW to instantly clear the command line. +2. If you are entering a new command, use the DOWN ARROW to instantly clear the command line. 3. Use TAB to switch between the various task lists e.g. uncompleted, overdue, upcoming + #### Saving the data -Agendum data is saved in the hard disk automatically after any command that changes the data.
-There is no need to save manually. +Agendum saves its data into the specified data storage location, or by default it saves into `todolist.xml`. This saving automatically happens whenever the task list is changed; There is no need to save manually. +   + ## FAQ -**Q**: How do I transfer my data to another Computer?
-**A**: Install Agendum in the other computer and overwrite the empty data file it creates with - the file that contains the data of your previous Agendum folder. + +
+
Q: How do I transfer my data to another computer?
+
Firstly, take note of the data storage location that your current todo list is saved at. You can check this by looking at the bottom-right of Agendum. Navigate to this location and copy the data file to a portable USB device or hard disk. Then, ensure that you have installed Agendum in the other computer. Copy the data file from your device onto the other computer, preferrably in the same folder as Agendum. Use the load command to load it into Agendum.
+ +
Q: Why did Agendum complain about an invalid file directory?
+
Check if the directory you wish to relocate to exists, or if you have enough administrator privileges.
+ +
Q: Can Agendum remind me when my task is due soon?
+
Agendum will always show the tasks that are due soon at the top of list. However, Agendum will not show you a reminder.
+ +
+   + ## Command Summary -Command | Format --------- | :-------- -Add | `add NAME [DATETIME]` -Alias |`alias OLD_COMMAND as NEW_COMMAND` -Delete | `delete INDEX` -Edit | `edit INDEX NAME` -Find | `find KEYWORD [MORE_KEYWORDS]` -Help | `help` -List | `list` -Mark | `mark INDEX` -Schedule | `schedule INDEX DATETIME` -Select | `select INDEX` -Store | `store DIRECTORY` -Unalias | `Unalias NEW_COMMAND` -Undo | `undo` -Unmark | `unmark INDEX` +Command | Format +:-------:| :-------- +Add | `add TASK_NAME [by DATE_TIME] [from START_DATE_TIME to END_DATE_TIME]` +Alias | `alias ORIGINAL_COMMAND_NAME NEW_COMMAND_NAME` +Delete | `delete INDEX...` +Exit | `exit` +Find | `find KEYWORD...` +Help | `help` +List | `list [TYPE]` +Load | `load PATH_TO_FILE` +Mark | `mark INDEX...` +Rename | `rename INDEX NEW_NAME` +Schedule | `schedule INDEX [by DATE_TIME] [from START_DATE_TIME to END_DATE_TIME]` +Select | `select INDEX` +Store | `store PATH_TO_FILE` +Unalias | `unalias NEW_COMMAND_NAME` or `unalias ORIGINAL_COMMAND_NAME` +Undo | `undo` +Unmark | `unmark INDEX...` diff --git a/docs/diagrams/Diagrams.pptx b/docs/diagrams/Diagrams.pptx index d249553472d2..bef2f8c0f110 100644 Binary files a/docs/diagrams/Diagrams.pptx and b/docs/diagrams/Diagrams.pptx differ diff --git a/docs/images/ModelClassDiagram.png b/docs/images/ModelClassDiagram.png index 5717f27f5884..2d0680007f97 100644 Binary files a/docs/images/ModelClassDiagram.png and b/docs/images/ModelClassDiagram.png differ diff --git a/docs/images/StorageClassDiagram.png b/docs/images/StorageClassDiagram.png index 5ad5877573f0..c6a4c260d08d 100644 Binary files a/docs/images/StorageClassDiagram.png and b/docs/images/StorageClassDiagram.png differ