Skip to content

Commit

Permalink
Merge pull request nus-cs2103-AY1718S1#56 from RonakLakhotia/UpdateDocs
Browse files Browse the repository at this point in the history
Updated docs
  • Loading branch information
RonakLakhotia authored Oct 20, 2017
2 parents afa3d79 + 2cb7565 commit 9ab7550
Show file tree
Hide file tree
Showing 19 changed files with 167 additions and 132 deletions.
4 changes: 2 additions & 2 deletions README.adoc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
image::docs/images/Present.png[width="790"]

= Weaver (Level 4)

image::docs/images/login.png[width="790"]

ifdef::env-github,env-browser[:relfileprefix: docs/]
ifdef::env-github,env-browser[:outfilesuffix: .adoc]

Expand Down
205 changes: 99 additions & 106 deletions docs/DeveloperGuide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -345,112 +345,6 @@ image::UndoRedoActivityDiagram.png[width="200"]
**Cons:** Requires dealing with commands that have already been undone: We must remember to skip these commands. Violates Single Responsibility Principle and Separation of Concerns as `HistoryManager` now needs to do two different things. +
// end::undoredo[]

<<<<<<< HEAD
// tag::deletepersontag[]
=== Deleting a Person's Tag mechanism

The Deleting a Person's Tag mechanism consists of `DeleteTagCommand` and `DeleteTagCommandParser` classes.

The `DeleteTagCommandParser` resides inside `LogicManager`.

`DeleteTagCommandParser` only deals with `Parser`. It is created from `AddressBookParser`. The following diagram shows the flow for parser:

image::LogicClassDiagram.png[width="800"]

As you can see from the diagram, `XYZCommand Parser` inherits from the `Parser` interface and is created by the AddressBook Parser as the `DeleteTagCommandParser`. Note that the tags are parsed under `parseTagsForDelete`, while the person index is parsed under `parse` before execution. The tags are identified by the prefix `t/` to be parsed for deletion, and it must be fully matched.

The `DeleteTagCommand` resides inside `LogicManager`. It supports undoing and redoing of that modifies the state of Weaver. Such commands will inherit from `UndoableCommand`.

`DeleteTagCommand` only deals with `UndoableCommands`. Commands that cannot be undone will inherit from `Command` instead. The following diagram shows the inheritance diagram for commands:

image::LogicCommandClassDiagram.png[width="800"]

As you can see from the diagram, `UndoableCommand` adds an extra layer between the abstract `Command` class and concrete commands that can be undone, such as the `DeleteTagCommand`. Note that extra tasks need to be done when executing a command in an _undoable_ way, such as saving the state of the address book before execution. `UndoableCommand` contains the high-level algorithm for those extra tasks while the child classes implements the details of how to execute the specific command. Note that this technique of putting the high-level algorithm in the parent class and lower-level steps of the algorithm in child classes is also known as the https://www.tutorialspoint.com/design_pattern/template_pattern.htm[template pattern].

Commands that are not undoable are implemented this way:
[source,java]
----
public class ListCommand extends Command {
@Override
public CommandResult execute() {
// ... list logic ...
}
}
----
With the extra layer, the commands that are undoable are implemented this way:
[source,java]
----
public abstract class UndoableCommand extends Command {
@Override
public CommandResult execute() {
// ... undo logic ...
executeUndoableCommand();
}
}
public class DeleteTagCommand extends UndoableCommand {
@Override
public CommandResult executeUndoableCommand() {
// ... delete logic ...
}
}
----

Inside the `DeleteTagCommand` class, a `DeleteTagDescriptor` identifying the tags to be deleted will be created from `DeleteTagCommandParser`, which will create and update a new `createTagDeletedPerson` accordingly. This will overwrite the existing `ReadOnlyPerson` Person's Tags while retaining the rest of its attributes as seen from the Model diagram below.

image::ModelClassDiagram.png[width="800"]

As you can see from the `Model` diagram, the `Person` retains the attributes that inherit it except for its own `UniqueTagList`, which is modified only for that particular `Person`.

Suppose that the user has just launched the application.

The user executes a new `DeleteTagCommand`, `delete/t 5 t/friends`, to delete the tag `friends` of the 5th person in the address book. The tags and the index are parsed into `DeleteTagCommandParser` before the `delete/t` command executes.

As the user continues to use the program, he might decide to delete more than one tags. For example, the user may execute `delete/t 2 t/colleagues t/friends` to delete multiple tags.

[NOTE]
If the tags are not fully matched, it will throw an `Exception`.

The user now decides that deleting the tags was a mistake, and decides to undo that action using `undo`.

Using the `Undo/Redo` stack, we will restore the address book to the state before the `delete/t` command is executed.

[NOTE]
If the `undoStack` is empty, then there are no other commands left to be undone, and an `Exception` will be thrown when popping the `undoStack`.

==== Design Considerations

**Aspect:** Implementation of `DeleteTagCommand` +
**Alternative 1 (current choice):** Access the `Person` and overwrite a new `Person` to it. +
**Pros:** We will not lose the same tags for other `Person` it is now part of the default behaviour. Classes that deal with `Tags` like `UniqueTagsList` do not have to be deleted. +
**Cons:** Hard for new developers to understand the `UniqueTagsList`. +
**Alternative 2:** Just delete the `Tag` in the `UniqueTagsList` +
**Pros:** Does not involve `Person` model, easier for new developers to understand with less coupling. +
**Cons:** It will defeat the purpose of deleting a tag solely of the specific `Person`. Might take more effort to organise tags for users.

---

**Aspect:** Implementation of `DeleteTagCommandParser` +
**Alternative 1 (current choice):** Able to utilise `Index` and tag prefix `t/`. +
**Pros:** Able to delete multiple tags, easy to implement. +
**Cons:** User will have to type additional prefixes to delete. +
**Alternative 2:** Not utilising prefix `t/`. +
**Pros:** Easier and faster to delete with no prefix identifier. +
**Cons:** Difficult to implement, as it is harder to tokenize the arguments to differentiate between index and tag.

---

**Aspect:** Deleting only a `Person` Tags +
**Alternative 1 (current choice):** If there are no tags for any `Person`, the `UniqueTagsList` will still contain that tag. +
**Pros:** Easy to implement. +
**Cons:** May have performance issues in terms of memory usage. +
**Alternative 2:** Clean up the `UniqueTagsList` after deleting its last tag. +
**Pros:** Will use less memory (e.g. for `UniqueTagsList`, will not contain tags that are not present in any `Person`). +
**Cons:** We must ensure that the implementation for discovering the last tags of the list is correct. May be harder to implement for new developers.

// end::deletepersontag[]

=== Login / Logout mechanism

The login / logout mechanism is a page which requires user to key in his username and password before he can use the addressbook. And Once he is logged in, there will be a automatically generated file named as "username + addressbook.xml" storing the information about his own addressbook.
Expand Down Expand Up @@ -685,6 +579,105 @@ If the `undoStack` is empty, then there are no other commands left to be undone,

// end::deletepersontag[]

// tag::addPhoto to Person[]
=== Adding a photo to a contact in your personalised Weaver.

The add Photo command adds a display picture to a particular contact.The command takes in two parameters, TargetIndex
that is the index of the person I want to add a photo and the image name with the extension. +
The command can also be used to delete an existing picture of a person.If the person has no display picture, an exception
will be thrown.


Format - photo [INDEX] [IMAGE_NAME.EXTENSION] +
e.g. `photo 1 Ronak.jpeg` to add an image
e.g. `photo 1 delete` to delete an existing image.

image::MockUp.png[width="800"]

The photo command is done with the help of ImageView property in JAVAFX, hence it is an attempt to enhance the UI. +

*PRE-REQUISITE* +
There is a pre-requisite for the command to work.The image that is going to be added to the contact must already be
present on the user's desktop.If it is not so, Weaver is going to prompt the user to add a valid File name.



The photo Command is inherited from the `UndoableCommand` class.

*Working Flow* +

The `PhotoCommandParser` Class parses the arguments entered in the photo command.The class then throws an Exception with the
appropriate message depending on whether the File name is not present on the Desktop or if the number of arguments entered
is not equal to two. +

The `PhotoCommand` class takes care of Invalid conditions like incorrect index. +

It then creates a new instance of the `FileImage` class. `FileImage` is an attribute that every person must have.
A new `Person` is created with the updated `FileImage` and the existing model is updated.

image::PhotoCommand.png[width="800"]

The `ModelManager` class implements the `addPhotoToPerson` method that adds a valid file image as an attribute to the person.

----
person.imageProperty().setValue( new FileImage(FilePath));
updateFilteredPersonList(PREDICATE_SHOW_ALL_PERSONS);
indicateAddressBookChanged();
----

`ImageStorage` class stores the image of each contact in the directory `/src/main/resources/images`.ImageIO class is used
for reading and writing of images.Each image is assigned a unique hashcode based on the email-id of the perosn.

----
image = new BufferedImage(963, 640, BufferedImage.TYPE_INT_ARGB);
fileToRead = new File(url);
image = ImageIO.read(fileToRead);
uniquePath = Integer.toString(newPath);
fileToWrite = new File("src/main/resources/images/" + uniquePath + ".jpg");
ImageIO.write(image, "jpg", fileToWrite);
----

*Sequence Diagram*

image::PhotoSequenceDiagram.png[width="800"]

==== Reasons for this type of implementation

* The feature can be implemented using CommandLine by just stating name of the file. +

* The index can be used easily used to reference the person. +

* The image gets stored in the local directory , so the user wont have to keep track of his/her copy of the image. +

==== Design Considerations

**Aspect:** How should the user choose the Image. +
**Alternative1 (current choice): ** Enter the name of the File present on
the desktop. +
**Pros:** Makes use of Commad Line Interface. +
**Cons:** User has to make sure the file exists on his/her Desktop. +
**Alternative2:** Make use of FileChooser that prompts user to choose file from
any directory. +
**Pros:** User can choose any image from any location. +
**Cons:** Makes use of a dialog box instead of Command Line. +

---

**Aspect:** How should the image be stored. +
**Alternative1 (current choice):** Image is stored in the `images` directory of the project by invoking `ImageStorage` class. +
**Pros:** Each image is assigned a unique hashcode. +
**Cons:** The working flow is not easy for incomimg developers to follow. +
**Alternative2:** Image should be stored from Model Component instead of Logic Component. +
**Pros:** Easy for new developers to comprehend. +
**Cons:** Two or more people may have the same id which is used to store the image. +

// end::addPhoto[]

// tag::Logging[]
=== Logging

We are using `java.util.logging` package for logging. The `LogsCenter` class is used to manage the logging levels and logging destinations.
Expand Down
43 changes: 34 additions & 9 deletions docs/UserGuide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,21 @@ This app will not work with earlier versions of Java 8.
. Copy the file to the folder you want to use as the home folder for your Address Book.
. Double-click the file to start the app. The GUI should appear in a few seconds.
+
image::login.png[width="790"]


. After login, you will see the GUI below.

image::Ui.png[width="790"]
+
image::MockUp.png[width="790"]

. Type the command in the command box and press kbd:[Enter] to execute it. +
e.g. typing *`help`* and pressing kbd:[Enter] will open the help window.
. Some example commands you can try:

* *`list`* : lists all contacts
* **`add`**`n/John Doe p/98765432 e/[email protected] a/John street, block 123, #01-01 b/13.10.1997` : adds a contact named `John Doe` to the Address Book.
* **`add`**`n/John Doe p/98765432 e/[email protected] a/John street, block 123, #01-01 b/13.10.1997 f/nus.jpg` : adds a contact named `John Doe` to the Address Book.
* **`delete`**`3` : deletes the 3rd contact shown in the current list
* *`exit`* : exits the app
* *`photo`* : Add a photo to a person

. Refer to the link:#features[Features] section below for details of each command.

Expand All @@ -62,15 +63,15 @@ Format: `help`
=== Adding a person: `add`

Adds a person to the address book +
Format: `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS b/DATE_OF_BIRTH [t/TAG]...`
Format: `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS b/DATE_OF_BIRTH f/FILE_PATH [t/TAG]...`

[TIP]
A person can have any number of tags (including 0)

Examples:

* `add n/John Doe p/98765432 e/[email protected] a/John street, block 123, #01-01 b/13.10.1997`
* `add n/Betsy Crowe t/friend e/[email protected] a/Newgate Prison p/1234567 b/13.10.1997 t/criminal`
* `add n/John Doe p/98765432 e/[email protected] a/John street, block 123, #01-01 b/13.10.1997 f/nus.jpg`
* `add n/Betsy Crowe t/friend e/[email protected] a/Newgate Prison p/1234567 b/13.10.1997 f/nus.jpg t/criminal`

=== Listing all persons : `list`

Expand Down Expand Up @@ -301,6 +302,9 @@ The `redo` command fails as there are no `undo` commands executed previously.
`redo` (reapplies the `clear` command) +
// end::undoredo[]

*SINCE V1.2*


=== Customize tags' color : `color`

Change the color of one or more than one tags. +
Expand Down Expand Up @@ -345,6 +349,25 @@ Examples:

* `fs -` +

=== Add Photo to contacts : `photo` +

image::MockUp.png[width="790"]

Adds a Display picture to the contact.The image file must be present on the desktop of the user.

e.g. `Photo 1 Ronak.jpg` adds the image `Ronak.jpg` to the contact with index 1 in the address book.

*Different Scenarios* :
****
1) Incorrect File entered - e.g `Photo 1 nus.jpg`
If 'nus.jpg' is not present on the desktop of the user, a prompt will be displayed to enter the correct file.
2) Delete an existing File - +
Command - Photo 1 Delete +
this will delete the photo attached with the person at index 1.
****


=== Clearing all entries : `clear`

Clears all entries from the address book. +
Expand Down Expand Up @@ -378,7 +401,7 @@ There is no need to save manually.
== Command Summary

* *Add* `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS b/DATE_OF_BIRTH [t/TAG]...` +
e.g. `add n/James Ho p/22224444 e/[email protected] a/123, Clementi Rd, 1234665 b/13.10.1997 t/friend t/colleague`
e.g. `add n/James Ho p/22224444 e/[email protected] a/123, Clementi Rd, 1234665 b/13.10.1997 f/ t/friend t/colleague`
* *Clear* : `clear`
* *Delete* : `delete INDEX` +
e.g. `delete 3`
Expand All @@ -392,7 +415,7 @@ e.g. `find James Jake`
e.g. `find/t friends family`
* *Customize tag color* : `color c/[COLOR] t/[TAG] t/[TAG] t/[MORE_TAGS]` +
e.g. `color c/red t/friend t/family`
* *Chang font size* : `fs [FONT SIZE]` or `fs +/-` +
* *Change font size* : `fs [FONT SIZE]` or `fs +/-` +
e.g. `fs xs` `fs +` `fs -`
* *List* : `list`
* *Help* : `help`
Expand All @@ -401,3 +424,5 @@ e.g.`select 2`
* *History* : `history`
* *Undo* : `undo`
* *Redo* : `redo`
* *Photo Index FilePath* : photo [Index] [FilePath] +
e.g. `photo 1 nus.jpg`
Binary file removed docs/diagrams/ChangeTagColorCommandClassDiagram.pptx
Binary file not shown.
Binary file removed docs/diagrams/ChangeTagColorSequenceDiagram.pptx
Binary file not shown.
Binary file added docs/diagrams/Photo.pptx
Binary file not shown.
Binary file added docs/diagrams/PhotoSequenceDiagram.pptx
Binary file not shown.
Binary file removed docs/images/ChangeTagColorCommandClassDiagram.png
Binary file not shown.
Binary file added docs/images/MockUp.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/PhotoCommand.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/PhotoSequenceDiagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion src/main/java/seedu/address/commons/core/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ public class Messages {
public static final String MESSAGE_INVALID_COMMAND_FORMAT = "Invalid command format! \n%1$s";
public static final String MESSAGE_INVALID_PERSON_DISPLAYED_INDEX = "The person index provided is invalid";
public static final String MESSAGE_PERSONS_LISTED_OVERVIEW = "%1$d persons listed!";
public static final String MESSAGE_INVALID_IMAGE = "Enter correct path";
public static final String MESSAGE_INVALID_IMAGE = "Enter correct path, your image file should be present."
+ "on the Desktop";
public static final String MESSAGE_NO_IMAGE_TO_DELETE = "The person has no Photo to be deleted.";

}
18 changes: 15 additions & 3 deletions src/main/java/seedu/address/logic/commands/PhotoCommand.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package seedu.address.logic.commands;

import java.io.IOException;

import java.util.List;

import seedu.address.commons.core.Messages;
Expand All @@ -24,9 +25,10 @@ public class PhotoCommand extends UndoableCommand {
public static final String MESSAGE_USAGE = COMMAND_WORD
+ ": Adds a photo of the person to the addressBook\n"
+ "Parameters: INDEX (must be a positive integer) FILE_PATH\n"
+ "File Path must be Valid\n"
+ "File Path must be Valid that is , must be present on the Desktop\n"
+ "Example: " + COMMAND_WORD + " 1" + " button.png";

public static final String DELETE_SUCCESS = "Deleted photo of Person: %1$s";
public static final String MESSAGE_PHOTO_PERSON_SUCCESS = "Added Photo to Person: %1$s";

public static final String MESSAGE_FILE_PATH_NOT_FOUND = "Incorrect file path";
Expand All @@ -50,6 +52,13 @@ public CommandResult executeUndoableCommand() throws CommandException {

ReadOnlyPerson personToAddPhoto = lastShownList.get(targetIndex.getZeroBased());

if (personToAddPhoto.getImage().getFilePath().equals("") && FilePath.equalsIgnoreCase("delete")) {
throw new CommandException(Messages.MESSAGE_NO_IMAGE_TO_DELETE);
}
if (FilePath.equalsIgnoreCase("Delete")) {
FilePath = "";
}

try {
Person editedPerson = new Person(personToAddPhoto.getName(), personToAddPhoto.getPhone(),
personToAddPhoto.getEmail(),
Expand All @@ -76,8 +85,11 @@ public CommandResult executeUndoableCommand() throws CommandException {
} catch (IllegalValueException ive) {
assert false : "Invalid input";
}

return new CommandResult(String.format(MESSAGE_PHOTO_PERSON_SUCCESS, personToAddPhoto));
if (FilePath.equals("")) {
return new CommandResult(String.format(DELETE_SUCCESS, personToAddPhoto));
} else {
return new CommandResult(String.format(MESSAGE_PHOTO_PERSON_SUCCESS, personToAddPhoto));
}
}

@Override
Expand Down
Loading

0 comments on commit 9ab7550

Please sign in to comment.