Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement rewind command feature #105

Merged
merged 4 commits into from
Oct 27, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/main/java/seedu/algobase/commons/core/Messages.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ public class Messages {
public static final String MESSAGE_INVALID_TAG_DISPLAYED_INDEX = "The Tag index provided is invalid";
public static final String MESSAGE_PLANS_LISTED_OVERVIEW = "%1$d plans listed!";
public static final String MESSAGE_INVALID_COMMAND_NAME = "Command %1$s not found!";
public static final String MESSAGE_INVALID_REWIND_NUMBER = "Invalid rewind number! (Is it larger than the "
+ "number of all successfully executed commands in this launch of AlgoBase?)";
}
6 changes: 6 additions & 0 deletions src/main/java/seedu/algobase/logic/LogicManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
import seedu.algobase.commons.core.LogsCenter;
import seedu.algobase.logic.commands.Command;
import seedu.algobase.logic.commands.CommandResult;
import seedu.algobase.logic.commands.RewindCommand;
import seedu.algobase.logic.commands.exceptions.CommandException;
import seedu.algobase.logic.parser.AlgoBaseParser;
import seedu.algobase.logic.parser.exceptions.ParseException;
import seedu.algobase.model.Model;
import seedu.algobase.model.ReadOnlyAlgoBase;
import seedu.algobase.model.commandhistory.CommandHistory;
import seedu.algobase.model.gui.GuiState;
import seedu.algobase.model.plan.Plan;
import seedu.algobase.model.problem.Problem;
Expand Down Expand Up @@ -45,6 +47,10 @@ public CommandResult execute(String commandText) throws CommandException, ParseE
CommandResult commandResult;
Command command = algoBaseParser.parseCommand(commandText);
commandResult = command.execute(model);
// We don't consider RewindCommand as a valid candidate to be stored in the command history.
if (!(command instanceof RewindCommand)) {
model.addCommandHistory(new CommandHistory(commandText)); // Save command text for rewind feature
}

try {
storage.saveAlgoBase(model.getAlgoBase());
Expand Down
18 changes: 13 additions & 5 deletions src/main/java/seedu/algobase/logic/commands/CommandResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,24 @@ public class CommandResult {
/** The application should exit. */
private final boolean exit;

private final boolean isRewind;

/**
* Constructs a {@code CommandResult} with the specified fields.
*/
public CommandResult(String feedbackToUser, boolean showHelp, boolean exit) {
public CommandResult(String feedbackToUser, boolean showHelp, boolean exit, boolean isRewind) {
this.feedbackToUser = requireNonNull(feedbackToUser);
this.showHelp = showHelp;
this.exit = exit;
this.isRewind = isRewind;
}

/**
* Constructs a {@code CommandResult} with the specified {@code feedbackToUser},
* and other fields set to their default value.
*/
public CommandResult(String feedbackToUser) {
this(feedbackToUser, false, false);
this(feedbackToUser, false, false, false);
le0tan marked this conversation as resolved.
Show resolved Hide resolved
}

public String getFeedbackToUser() {
Expand All @@ -46,6 +49,10 @@ public boolean isExit() {
return exit;
}

public boolean isRewind() {
return isRewind;
}

@Override
public boolean equals(Object other) {
if (other == this) {
Expand All @@ -59,13 +66,14 @@ public boolean equals(Object other) {

CommandResult otherCommandResult = (CommandResult) other;
return feedbackToUser.equals(otherCommandResult.feedbackToUser)
&& showHelp == otherCommandResult.showHelp
&& exit == otherCommandResult.exit;
&& showHelp == otherCommandResult.showHelp
&& exit == otherCommandResult.exit
&& isRewind == otherCommandResult.isRewind;
}

@Override
public int hashCode() {
return Objects.hash(feedbackToUser, showHelp, exit);
return Objects.hash(feedbackToUser, showHelp, exit, isRewind);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class ExitCommand extends Command {

@Override
public CommandResult execute(Model model) {
return new CommandResult(MESSAGE_EXIT_ACKNOWLEDGEMENT, false, true);
return new CommandResult(MESSAGE_EXIT_ACKNOWLEDGEMENT, false, true, false);
}

}
4 changes: 2 additions & 2 deletions src/main/java/seedu/algobase/logic/commands/HelpCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ public CommandResult execute(Model model) {
}
String commandPrompt = "Available commands are: " + commandWords.toString() + "\n"
+ "More information can be found in the popup window.";
return new CommandResult(commandPrompt, true, false);
return new CommandResult(commandPrompt, true, false, false);
} else {
String commandUsage = getClassStringField(commandClass, "MESSAGE_USAGE");
return new CommandResult(commandUsage, false, false);
return new CommandResult(commandUsage);
}
}

Expand Down
47 changes: 47 additions & 0 deletions src/main/java/seedu/algobase/logic/commands/RewindCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package seedu.algobase.logic.commands;

import static java.util.Objects.requireNonNull;

import java.util.List;

import seedu.algobase.commons.core.Messages;
import seedu.algobase.commons.core.index.Index;
import seedu.algobase.logic.commands.exceptions.CommandException;
import seedu.algobase.model.Model;
import seedu.algobase.model.commandhistory.CommandHistory;

/**
* Rewinds the content of CommandBox to a previous successfully executed command.
*/
public class RewindCommand extends Command {

public static final String COMMAND_WORD = "rewind";

public static final String MESSAGE_USAGE = COMMAND_WORD
+ ": Rewinds the command input to a previous successfully executed command input.\n"
+ "Parameters: INDEX (must be a positive integer, represents how many commands ago you want to rewind to)\n"
+ "Example: " + COMMAND_WORD + " 1";

public static final String MESSAGE_SUCCESS = "Rewind successfully!";
public static final String REWIND_TO_LAST_COMMAND_TEXT = COMMAND_WORD + " 1";

private final Index targetIndex;

public RewindCommand(Index targetIndex) {
this.targetIndex = targetIndex;
}

@Override
public CommandResult execute(Model model) throws CommandException {
requireNonNull(model);
List<CommandHistory> commandHistories = model.getCommandHistoryList();

if (targetIndex.getOneBased() > commandHistories.size()) {
throw new CommandException(Messages.MESSAGE_INVALID_REWIND_NUMBER);
}

CommandHistory commandHistoryToShow = commandHistories.get(
commandHistories.size() - targetIndex.getOneBased());
return new CommandResult(commandHistoryToShow.getCommandText(), false, false, true);
le0tan marked this conversation as resolved.
Show resolved Hide resolved
}
}
5 changes: 5 additions & 0 deletions src/main/java/seedu/algobase/logic/parser/AlgoBaseParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import seedu.algobase.logic.commands.ListPlanCommand;
import seedu.algobase.logic.commands.ListTagCommand;
import seedu.algobase.logic.commands.OpenTabCommand;
import seedu.algobase.logic.commands.RewindCommand;
import seedu.algobase.logic.commands.SortCommand;
import seedu.algobase.logic.commands.SwitchTabCommand;
import seedu.algobase.logic.commands.UndoneTaskCommand;
Expand Down Expand Up @@ -108,6 +109,10 @@ public Command parseCommand(String userInput) throws ParseException {
case UndoneTaskCommand.COMMAND_WORD:
return new UndoneTaskCommandParser().parse(arguments);

//Rewind
case RewindCommand.COMMAND_WORD:
return new RewindCommandParser().parse(arguments);

//Util
case ClearCommand.COMMAND_WORD:
return new ClearCommand();
Expand Down
31 changes: 31 additions & 0 deletions src/main/java/seedu/algobase/logic/parser/RewindCommandParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package seedu.algobase.logic.parser;

import static seedu.algobase.commons.core.Messages.MESSAGE_INVALID_COMMAND_FORMAT;

import seedu.algobase.commons.core.index.Index;
import seedu.algobase.logic.commands.RewindCommand;
import seedu.algobase.logic.parser.exceptions.ParseException;

/**
* Parses input arguments and creates a new RewindCommand object
*/
public class RewindCommandParser implements Parser<RewindCommand> {

/**
* Parses {@code userInput} into a command and returns it.
*
* @param args the user input to be parsed
* @throws ParseException if {@code userInput} does not conform the expected format
*/
@Override
public RewindCommand parse(String args) throws ParseException {
try {
Index index = ParserUtil.parseIndex(args);
return new RewindCommand(index);
} catch (ParseException pe) {
throw new ParseException(
String.format(MESSAGE_INVALID_COMMAND_FORMAT, RewindCommand.MESSAGE_USAGE), pe);
}
}

}
20 changes: 19 additions & 1 deletion src/main/java/seedu/algobase/model/AlgoBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

import javafx.collections.ObservableList;
import seedu.algobase.commons.exceptions.IllegalValueException;
import seedu.algobase.model.commandhistory.CommandHistory;
import seedu.algobase.model.commandhistory.CommandHistoryList;
import seedu.algobase.model.plan.Plan;
import seedu.algobase.model.plan.PlanList;
import seedu.algobase.model.problem.Problem;
Expand All @@ -17,13 +19,13 @@

/**
* Wraps all data at the algobase level
* Duplicates are not allowed (by .isSameProblem comparison)
*/
public class AlgoBase implements ReadOnlyAlgoBase {

private final UniqueProblemList problems;
private final UniqueTagList tags;
private final PlanList plans;
private final CommandHistoryList commandHistories;

/*
* The 'unusual' code block below is a non-static initialization block, sometimes used to avoid duplication
Expand All @@ -36,6 +38,7 @@ public class AlgoBase implements ReadOnlyAlgoBase {
problems = new UniqueProblemList();
plans = new PlanList();
tags = new UniqueTagList();
commandHistories = new CommandHistoryList();
}

public AlgoBase() {}
Expand Down Expand Up @@ -225,6 +228,21 @@ public ObservableList<Task> getCurrentTaskList() {
return plans.getUnmodifiableObservableTaskList();
}

//========== Rewind =================================================================

@Override
public ObservableList<CommandHistory> getCommandHistoryList() {
return commandHistories.asUnmodifiableObservableList();
}

/**
* Adds a {@code CommandHistroy} to AlgoBase.
*/
public void addCommandHistory(CommandHistory history) {
requireNonNull(history);
commandHistories.add(history);
}

//========== Util ===================================================================

@Override
Expand Down
16 changes: 15 additions & 1 deletion src/main/java/seedu/algobase/model/Model.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package seedu.algobase.model;

import java.nio.file.Path;

import java.util.Comparator;
import java.util.Set;
import java.util.function.Predicate;

import javafx.collections.ObservableList;
import seedu.algobase.commons.core.GuiSettings;
import seedu.algobase.model.commandhistory.CommandHistory;
import seedu.algobase.model.gui.GuiState;
import seedu.algobase.model.plan.Plan;
import seedu.algobase.model.problem.Problem;
Expand Down Expand Up @@ -206,4 +206,18 @@ public interface Model {

/** Returns an unmodifiable view of the filtered Plan list */
ObservableList<Task> getCurrentTaskList();

//=========== Rewind ================================================================

/**
* Returns an unmodifiable view of the filtered CommandHistory list.
*/
ObservableList<CommandHistory> getCommandHistoryList();

/**
* Adds the given {@code CommandHistory}.
* @param history the added history
*/
void addCommandHistory(CommandHistory history);

}
28 changes: 26 additions & 2 deletions src/main/java/seedu/algobase/model/ModelManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import javafx.collections.transformation.SortedList;
import seedu.algobase.commons.core.GuiSettings;
import seedu.algobase.commons.core.LogsCenter;
import seedu.algobase.model.commandhistory.CommandHistory;
import seedu.algobase.model.gui.GuiState;
import seedu.algobase.model.plan.Plan;
import seedu.algobase.model.problem.Problem;
Expand All @@ -34,6 +35,7 @@ public class ModelManager implements Model {
private final SortedList<Problem> sortedProblems;
private final FilteredList<Plan> filteredPlans;
private final FilteredList<Task> filteredTasks;
private final FilteredList<CommandHistory> filteredCommandHistories;

/**
* Initializes a ModelManager with the given algoBase and userPrefs.
Expand All @@ -52,6 +54,7 @@ public ModelManager(ReadOnlyAlgoBase algoBase, ReadOnlyUserPrefs userPrefs) {
sortedProblems = new SortedList<>(filteredProblems);
filteredPlans = new FilteredList<>(this.algoBase.getPlanList());
filteredTasks = new FilteredList<>(this.algoBase.getCurrentTaskList());
filteredCommandHistories = new FilteredList<>(this.algoBase.getCommandHistoryList());
}

public ModelManager() {
Expand Down Expand Up @@ -137,8 +140,7 @@ public void setProblem(Problem target, Problem editedProblem) {
}

/**
* Returns an unmodifiable view of the list of {@code Problem} backed by the internal list of
* {@code versionedAlgoBase}
* Returns an unmodifiable view of the list of {@code Problem}.
*/
@Override
public ObservableList<Problem> getFilteredProblemList() {
Expand Down Expand Up @@ -288,6 +290,28 @@ public ObservableList<Task> getCurrentTaskList() {
return filteredTasks;
}

//========== Rewind =================================================================

/**
* Returns an unmodifiable view of the list of {@code CommandHistory}.
*/
@Override
public ObservableList<CommandHistory> getCommandHistoryList() {
return filteredCommandHistories;
}

/**
* Adds the given {@code CommandHistory}.
*
* @param history the added history
*/
@Override
public void addCommandHistory(CommandHistory history) {
requireNonNull(history);
algoBase.addCommandHistory(history);
}


//========== Util ===================================================================

@Override
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/seedu/algobase/model/ReadOnlyAlgoBase.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package seedu.algobase.model;

import javafx.collections.ObservableList;
import seedu.algobase.model.commandhistory.CommandHistory;
import seedu.algobase.model.plan.Plan;
import seedu.algobase.model.problem.Problem;
import seedu.algobase.model.tag.Tag;
Expand Down Expand Up @@ -28,4 +29,9 @@ public interface ReadOnlyAlgoBase {
*/
ObservableList<Task> getCurrentTaskList();

/**
* Returns an unmodifiable view of the command history.
*/
ObservableList<CommandHistory> getCommandHistoryList();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package seedu.algobase.model.commandhistory;

/**
* Represents a command history in AlgoBase.
*/
public class CommandHistory {
private final String commandText;

public CommandHistory(String commandText) {
this.commandText = commandText;
}

public String getCommandText() {
return commandText;
}
}
Loading