## 1. Introduction
Welcome to the developer guide for SmartyDo. This guide is meant to enable budding developers like yourself to better understand the implementation of our program. Through this guide, we hope that you will be able to learn not only about how SmartyDo is implemented, but about different parts of the application that you are able to improve yourself.
## 2. Setting up
#### 2.1 Prerequisites
To ensure that you are able to run SmartyDo smoothly, do ensure that you have met the following prerequisites:
1. Installed **JDK `1.8.0_60`** or later<br>
> This app may not work as intended with earlier versions of Java 8. <br>
This app will not work with earlier versions of Java.
2. Installed **Eclipse** IDE
3. Installed **e(fx)clipse** plugin for Eclipse (Follow the instructions given on
[this page](http://www.eclipse.org/efxclipse/install.html#for-the-ambitious))
4. Installed **Buildship Gradle Integration** plugin from the Eclipse Marketplace
#### 2.2 Importing the project into Eclipse
To import the lastest version of this project into Eclipse, follow the instructions as given below:
0. Fork this repo, and clone the fork to your computer
1. Open Eclipse (Note: Ensure you have installed the **e(fx)clipse** and **buildship** plugins as given
in the prerequisites above)
2. Click `File` > `Import`
3. Click `Gradle` > `Gradle Project` > `Next` > `Next`
4. Click `Browse`, then locate the project's directory
5. 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. Design
### 3.1 Architecture
The **_Architecture Diagram_** given above will explain to you the high-level design of the App. Below, we will give you a quick overview of each component.
<img src="images/Architecture.png" width="600"><br>Figure 1. Overview of Main
`Main` has only one class called [`MainApp`](../src/main/java/seedu/address/MainApp.java). It is responsible for,
* At app launch: `Main` will initialize the components in the correct sequence, and connect them up with each other.
* At shut down: `Main` will shut down the components and invoke cleanup method where necessary.
[**`Commons`**](#36-common-classes) represents a collection of classes used by multiple other components.
Two of those classes play important roles at the architecture level.
* `EventsCentre`: This class (written using [Google's Event Bus library](https://github.com/google/guava/wiki/EventBusExplained))
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.
* [**`UI`**](#ui-component): The UI of the App.
* [**`Logic`**](#logic-component): Executes commands given by the user.
* [**`Model`**](#model-component): Holds the data of the App in-memory.
* [**`Storage`**](#storage-component): Reads data from, and writes data to the hard disk.
Each of the four components will
* Define its _API_ in an `interface` with the same name as the Component.
* Expose its functionality using a `{Component Name}Manager` class.
For example, the `Logic` component (see the class diagram given below) defines it's API in the `Logic.java`
interface and exposes its functionality using the `LogicManager.java` class.<br>
<img src="images/LogicClassDiagram.png" width="800"><br>Figure 2. Overview of Logic<br>
The _Sequence Diagram_ below will show you how the components interact for the scenario where the user issues the
command `delete 3`.
<img src="images\SDforDeletePerson.png" width="800"><br>Figure 3. Sequence Diagram: Delete 1<br>
>Note how the `Model` simply raises a `ToDoChangedEvent` when the To-Do data are changed,
instead of asking the `Storage` to save the updates to the hard disk.
The diagram below will show you 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. <br>
<img src="images\SDforDeletePersonEventHandling.png" width="800"><br>Figure 4. Sequence Diagram: ToDoEventChange<br>
> 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
coupling between components.
The follwing sections will give you more details about each component.
### 3.2 UI component
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`.
<img src="images/UiClassDiagram.png" width="800"><br>Figure 5. Overview of UI<br>
**API** : [`Ui.java`](../src/main/java/seedu/address/ui/Ui.java)
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.<br>
For example, the layout of the [`MainWindow`](../src/main/java/seedu/address/ui/MainWindow.java) is specified in
[`MainWindow.fxml`](../src/main/resources/view/MainWindow.fxml)
The `UI` component will
* Execute user commands using the `Logic` component.
* Bind itself to some data in the `Model` so that the UI can auto-update when data in the `Model` change.
* Respond to events raised from various parts of the App and updates the UI accordingly.
### 3.3 Logic component
Logic is in charge of reading user input and executing the correct commands. It is also in charge of give the user feedback on their input.
<img src="images/LogicClassDiagram.png" width="800"><br>Figure 6. Overview of Logic <br>
**API** : [`Logic.java`](../src/main/java/seedu/address/logic/Logic.java)
1. `Logic` uses the `Parser` class to parse the user command.
2. This results in a `Command` object which is executed by the `LogicManager`.
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`.
5. `Logic` loads the `undo/redo Manager` which is initially an empty stack. If the command that is recently executed successfully belongs to a undoable command, the undo/redo manager will record it.
Below, you will find the Sequence Diagram for interactions within the `Logic` component for the `execute("delete 1")`
API call.<br>
<img src="images/DeletePersonSdForLogic.png" width="800"><br>Figure 7. Sequence Diagram: Delete in Logic<br>
### 3.4 Model component
Model is in charge of the structure of the to-do list, and serves as the manager of the abstraction layer between Logic and the actual list of tasks.
<img src="images/ModelClassDiagram.png" width="800"><br>Figure 8. Overview of Model<br>
**API** : [`Model.java`](../src/main/java/seedu/address/model/Model.java)
The `Model`,
* stores a `UserPref` object that represents the user's preferences.
* stores the To-Do data.
* exposes a `UnmodifiableObservableList<ReadOnlyTask>` 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.
### 3.5 Storage component
Storage is in charge of saving and retrieving data from files stored on the user’s device.
<img src="images/StorageClassDiagram.png" width="800"><br>Figure 9. Overview of Storage<br>
**API** : [`Storage.java`](../src/main/java/seedu/address/storage/Storage.java)
The `Storage` component,
* can save `UserPref` objects in json format and read it back.
* can save the SmartyDo data in xml format and read it back.
### 3.6 Common classes
You may find classes used by multiple components are in the `seedu.addressbook.commons` package.
## 4. Implementation
### 4.1 Logging
We are using `java.util.logging` package for logging. You can use `LogsCenter` class to manage the logging levels
and logging destinations.
* You can control the logging level by using the `logLevel` setting in the configuration file
(See [Configuration](#configuration))
* You can obtain the `Logger` for a class by 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.
**Logging Levels**
|Level|Details|
|---|---|
| `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 are not usually noteworthy but may be useful in debugging e.g. printout of the actual list instead of just its size
### 4.2 Configuration
You can control certain properties of the application (e.g App name, logging level) through the configuration file
(default: `config.json`):
## 5. Testing
You can find tests in the `./src/test/java` folder.
**In Eclipse**:
> If you are not using a recent Eclipse version (i.e. _Neon_ or later), you will need to enable assertions in JUnit tests
as described [here](http://stackoverflow.com/questions/2522897/eclipse-junit-ea-vm-option).
* You can run all tests by right-clicking on the `src/test/java` folder and choose
`Run as` > `JUnit Test`
* You can also run a subset of tests by right-clicking on a test package, test class, or a test and choose
to run as a JUnit test.
**Using Gradle**:
* You may refer to [UsingGradle.md](UsingGradle.md) to see how to run tests using Gradle.
We have two types of tests:
1. **GUI Tests** - These are _System Tests_ that test the entire App by simulating user actions on the GUI.
These are in the `guitests` package.
2. **Non-GUI Tests** - These are tests not involving the GUI. They include,
1. _Unit tests_ targeting the lowest level methods/classes. <br>
e.g. `seedu.address.commons.UrlUtilTest`
2. _Integration tests_ that are checking the integration of multiple code units
(those code units are assumed to be working).<br>
e.g. `seedu.address.storage.StorageManagerTest`
3. _Hybrids of unit and integration tests._ These test are checking multiple code units as well as
how they are connected together.<br>
e.g. `seedu.address.logic.LogicManagerTest`
**Headless GUI Testing** :
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.<br>
See [UsingGradle.md](UsingGradle.md#running-tests) to learn how to run tests in headless mode.
## 6. Dev Ops
### 6.1 Build Automation
You may read [UsingGradle.md](UsingGradle.md) to learn how to use Gradle for build automation.
### 6.2 Continuous Integration
We use [Travis CI](https://travis-ci.org/) to perform _Continuous Integration_ on our projects.
You may read [UsingTravis.md](UsingTravis.md) for more details.
### 6.3 Making a Release
Here are the steps to create 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.
### 6.4 Managing Dependencies
A project often depends on third-party libraries. For example, SmartyDo 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.<br>
a. Include those libraries in the repo (this bloats the repo size)<br>
b. Require developers to download those libraries manually (this creates extra work for developers)<br>
## 7. Appendix
## 7.3 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 2 years of entries estimated to be 8000 entries.
3. Should come with automated unit tests and open source code.
4. Should favor DOS style commands over Unix-style commands.
## 1. Introduction
SmartyDo is a **to-do-list** application. With SmartyDo, forgetting upcoming deadlines and sleepless nights over incomplete tasks are a thing of the past. SmartyDo **increases your efficiency** by showing the lists of tasks that can be completed simultaneously. Treat SmartyDo like your personal assistant and just focus on **completing your tasks**!
## 2. Quick Start
**Launch SmartyDo**: Simply double-click on the `SmartyDo.jar` file to start SmartyDo. You will be greeted with a simple interface that has three components: a **Visual Box**, a **Message Box** and a **Command Bar**.
<img src="images/mainScreen.png" width="250"><br>Figure 1. Welcome Screen<br>
**Command Bar** is where you enter short commands to tell SmartyDo what to do.<br>
**Visual Box** is where you can see a comprehensive list of your tasks.<br>
**Message Box** shows the result of your command.<br>
### 3.4. **Adding Tasks Into SmartyDo**
You can add a task into SmartyDo by using the add command. There are number of parameters that you can use to add more details to the task. Below is a summary of the various parameters and their usage:<br>
Here is the summary of the parameters and their usage:
| Parameter | Flag | Format Requirements | Optional |
| ------------- |:-------------:| -----:|:---:|
| `TASK_NAME` | | _**n;**_ required if `TASK_NAME` is not the first parameter | No |
| `DATE_TIME` | **t;** | [Date] [Start_Time] [End_Time] , delimited by spaces | Yes |
| `TAG` | _**t/**_ | alphanumeric | Yes |
| `LOCATION` | _**a;**_ | alphanumeric | Yes |
| `DESCRIPTION` | _**d;**_ | alphanumeric | Yes |
Table 3.2. Add Command Parameters
- `TASK_NAME` is the name of the task and this parameter is compulsary.
- `Date` is the date of the task supports date format of
dd/mmm/yyyy eg:20-Jan-2017 and dd/mm/yyyy with `/` interchangleable with `.` and `-` eg: 20-01-2017.
- `START_TIME` and `END_TIME` is the starting time and ending time of the task respectively. You may consider to use these parameters when starting time and/or deadline is known. You may omit the details of 'DATE_TIME' which will result in a task that has no time frame.
- `TAG` is the characteristic you can add to the task. Such tags can be "Urgent", "HighPriority" and etc.
- `LOCATION` is the place of task being done. You can use this parameter to remind you where to go to complete the task.
- 'DESCRIPTION' is where you can include some extra information about your task.
Format : `add TASK_NAME [t; DATE START_TIME] [a;LOCATION] [t/TAG] [d;`
> You don't have to enter the optional parameters when you don't need them. The order of the parameters are not fixed. You can enter the parameters in any order. For example, `add t/[TAG] t; DATE START_TIME ` is also correct format.
**Example:**<br>
Let's say you want to add task named "Presentation" which is scheduled for 18 July 2016, 9:00AM. All you need to do is enter the following as shown below.
<img src="images/addCommand.png" width="250" align="middle"><br>Figure 5. Example of add command<br>
After entering the command, MessageBox will show you task is successfully added into SmartyDo and you will see the updated list of task in the Visual Box.
### 3.13. **Clearing Saved Data**
You may clear all data stored in SmartyDo by using the `clear` command. SmartyDo will prompt you to confirm this action. Enter `yes` to complete the command. Entering a different command will cancel the `clear` command.
Format: `clear`
**Example**<br>
If you wish to clear all data in SmartyDo, you many enter `clear` into the CommandBox.
<img src="images/clearConfirmCommand.png" width="500" align="middle"><br>Figure 14. Example of locate command<br>
After entering the command, a prompt will appear in the MessageBox asking you to confirm this action. Enter `yes` to proceed.
### 3.14. **Exiting SmartyDo**
After using SmartyDo, you can exit the program by using `exit` command.
Format: `exit`
By entering `exit` command in the command box, SmartyDo will quit and save the data.
## 4. Smart Features
### 4.1. **FlexiCommand**
It is okay if you cannot remember the syntax entirely! As long as you remember the keyword some reshuffling of the parameters entered is fine. Our program will ask you for confirmation if we are unsure what you want.
### 4.2. **Saving the Data**
SmartyDo will automatically save your data in the hard disk after any command that changes the data. There is no need to save manually.