Merge branch 'master' of https://gitlab.stud.idi.ntnu.no/oysteikt/h20-tdt4100-project
This commit is contained in:
commit
48250b6bd0
@ -13,7 +13,6 @@ import app.controllers.*;
|
|||||||
import app.events.ExitApplicationEvent;
|
import app.events.ExitApplicationEvent;
|
||||||
import app.events.LanguageChangedEvent;
|
import app.events.LanguageChangedEvent;
|
||||||
import app.events.OpenLinkInBrowserEvent;
|
import app.events.OpenLinkInBrowserEvent;
|
||||||
import app.events.SaveFileEvent;
|
|
||||||
import app.events.ThemeChangedEvent;
|
import app.events.ThemeChangedEvent;
|
||||||
import app.model.Model;
|
import app.model.Model;
|
||||||
import javafx.application.HostServices;
|
import javafx.application.HostServices;
|
||||||
@ -21,6 +20,9 @@ import javafx.application.Platform;
|
|||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.Initializable;
|
import javafx.fxml.Initializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An FXML controller that controls the application and all subcontrollers
|
||||||
|
*/
|
||||||
public class MainController implements Initializable {
|
public class MainController implements Initializable {
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
@ -67,7 +69,9 @@ public class MainController implements Initializable {
|
|||||||
return hostServices;
|
return hostServices;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Document
|
/**
|
||||||
|
* @return All subcontrollers of this controller
|
||||||
|
*/
|
||||||
public List<Controller> getInnerControllers() {
|
public List<Controller> getInnerControllers() {
|
||||||
return List.of(editorController, filetreeController, modelineController, menubarController);
|
return List.of(editorController, filetreeController, modelineController, menubarController);
|
||||||
}
|
}
|
||||||
@ -95,13 +99,17 @@ public class MainController implements Initializable {
|
|||||||
Model.getScene().getStylesheets().set(position, nextStyleSheet);
|
Model.getScene().getStylesheets().set(position, nextStyleSheet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
/* EVENT BUS LISTENERS */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change the CSS according to which language is being used
|
* Change the CSS according to which language is being used
|
||||||
*
|
*
|
||||||
* @param event
|
* @param event
|
||||||
*/
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void handle(LanguageChangedEvent event) {
|
public void handle(LanguageChangedEvent event) {
|
||||||
this.setCSSAt(1, "/styling/languages/" + event.getLanguage().toLowerCase() + ".css");
|
this.setCSSAt(1, "/styling/languages/" + event.getLanguage().toLowerCase() + ".css");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +119,7 @@ public class MainController implements Initializable {
|
|||||||
* @param event
|
* @param event
|
||||||
*/
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void handle(ThemeChangedEvent event) {
|
public void handle(ThemeChangedEvent event) {
|
||||||
this.setCSSAt(0, "/styling/themes/" + event.getTheme().toLowerCase().replace(" ", "-") + ".css");
|
this.setCSSAt(0, "/styling/themes/" + event.getTheme().toLowerCase().replace(" ", "-") + ".css");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,7 +129,7 @@ public class MainController implements Initializable {
|
|||||||
* @param event
|
* @param event
|
||||||
*/
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void handle(OpenLinkInBrowserEvent event) {
|
public void handle(OpenLinkInBrowserEvent event) {
|
||||||
this.getHostServices().showDocument(event.getLink());
|
this.getHostServices().showDocument(event.getLink());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,18 +141,14 @@ public class MainController implements Initializable {
|
|||||||
* @param event
|
* @param event
|
||||||
*/
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void handle(ExitApplicationEvent event) {
|
public void handle(ExitApplicationEvent event) {
|
||||||
if (!Model.getFileIsSaved()) {
|
if (!Model.getFileIsSaved()) {
|
||||||
int g = JOptionPane.showConfirmDialog(null, "Your files are not saved.\nSave before exit?", "Exit",
|
int g = JOptionPane.showConfirmDialog(null, "Your files are not saved.\nSave before exit?", "Exit",
|
||||||
JOptionPane.YES_NO_OPTION);
|
JOptionPane.YES_NO_OPTION);
|
||||||
|
|
||||||
if (g == JOptionPane.YES_OPTION) {
|
if (g == JOptionPane.YES_OPTION)
|
||||||
this.eventBus.post(new SaveFileEvent());
|
this.editorController.saveCodeArea(Model.getActiveFilePath().isEmpty());
|
||||||
Platform.exit();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Platform.exit();
|
|
||||||
}
|
}
|
||||||
|
Platform.exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
package app;
|
package app;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A launcher class to point towards as the start point for a packaged JAR
|
||||||
|
*/
|
||||||
public class MainLauncher {
|
public class MainLauncher {
|
||||||
|
/**
|
||||||
|
* The root function of the call stack
|
||||||
|
*
|
||||||
|
* @param args Commandline arguments
|
||||||
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Main.main(args);
|
Main.main(args);
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,12 @@ package app.controllers;
|
|||||||
import com.google.common.eventbus.EventBus;
|
import com.google.common.eventbus.EventBus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface describing a controller that contains an EventBus
|
* Interface describing a JavaFX controller that contains an EventBus
|
||||||
*/
|
*/
|
||||||
public interface Controller {
|
public interface Controller {
|
||||||
/**
|
/**
|
||||||
* Registers the main EventBus into the controller.
|
* Registers the main EventBus into the controller.
|
||||||
* @param eventBus The EventBus
|
* @param eventBus
|
||||||
*/
|
*/
|
||||||
public void setEventBus(EventBus eventBus);
|
public void setEventBus(EventBus eventBus);
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ import javafx.fxml.Initializable;
|
|||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A FXML controller that controls the editor component of the UI
|
* An FXML controller that controls the CodeArea
|
||||||
*/
|
*/
|
||||||
public class EditorController implements Initializable, Controller {
|
public class EditorController implements Initializable, Controller {
|
||||||
|
|
||||||
@ -60,15 +60,10 @@ public class EditorController implements Initializable, Controller {
|
|||||||
this.eventBus.register(this);
|
this.eventBus.register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: document
|
|
||||||
public CodeArea getEditor() {
|
|
||||||
return editor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies highlighting to the editor.
|
* Applies highlighting to the editor.
|
||||||
*
|
*
|
||||||
* @param highlighting highlighting data
|
* @param highlighting Syntax highlighting data
|
||||||
*/
|
*/
|
||||||
private void setHighlighting(StyleSpans<Collection<String>> highlighting) {
|
private void setHighlighting(StyleSpans<Collection<String>> highlighting) {
|
||||||
this.editor.setStyleSpans(0, highlighting);
|
this.editor.setStyleSpans(0, highlighting);
|
||||||
@ -90,7 +85,6 @@ public class EditorController implements Initializable, Controller {
|
|||||||
* ProgrammingLanguage.commentLine(line)
|
* ProgrammingLanguage.commentLine(line)
|
||||||
*/
|
*/
|
||||||
private void toggleComment() {
|
private void toggleComment() {
|
||||||
// TODO: This logic might need to be moved to LanguageOperations
|
|
||||||
if (editor.getSelectedText().equals("")) {
|
if (editor.getSelectedText().equals("")) {
|
||||||
String currentLine = editor.getText(editor.getCurrentParagraph());
|
String currentLine = editor.getText(editor.getCurrentParagraph());
|
||||||
|
|
||||||
@ -118,7 +112,7 @@ public class EditorController implements Initializable, Controller {
|
|||||||
/**
|
/**
|
||||||
* Updates the wraptext setting of the code area
|
* Updates the wraptext setting of the code area
|
||||||
*
|
*
|
||||||
* @param isWrapText The new value for the setting
|
* @param isWrapText The updated setting value
|
||||||
*/
|
*/
|
||||||
private void setWrapText(boolean isWrapText) {
|
private void setWrapText(boolean isWrapText) {
|
||||||
this.editor.setWrapText(isWrapText);
|
this.editor.setWrapText(isWrapText);
|
||||||
@ -143,20 +137,20 @@ public class EditorController implements Initializable, Controller {
|
|||||||
*
|
*
|
||||||
* @param newContent The String to be inserted into the editor
|
* @param newContent The String to be inserted into the editor
|
||||||
*/
|
*/
|
||||||
public void setEditorContent(String newContent) {
|
private void setEditorContent(String newContent) {
|
||||||
editor.clear();
|
editor.clear();
|
||||||
editor.appendText(newContent);
|
editor.appendText(newContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saving/Writing to the file based on the spesific filepath. Otherwise it will
|
* Saving/Writing to the file based on the active filepath in {@link app.model.Model Model}
|
||||||
* open an error dialog to give the user feedback about what has happened.
|
* if it is a new File. Otherwise it will open a dialog to ask the user where to save the file.
|
||||||
|
*
|
||||||
|
* @param isNewFile Whether or not the file already has a path
|
||||||
*/
|
*/
|
||||||
public void saveCodeArea(boolean isNewFile) {
|
public void saveCodeArea(boolean isNewFile) {
|
||||||
Stage stage = (Stage) editor.getScene().getWindow();
|
Stage stage = (Stage) editor.getScene().getWindow();
|
||||||
|
|
||||||
isNewFile = Model.getActiveFilePath().isEmpty();
|
|
||||||
|
|
||||||
if (isNewFile && FileOperations.saveFileWithDialog(stage, editor.getText())) {
|
if (isNewFile && FileOperations.saveFileWithDialog(stage, editor.getText())) {
|
||||||
this.eventBus.post(new OpenFileEvent(Model.getActiveFilePath()));
|
this.eventBus.post(new OpenFileEvent(Model.getActiveFilePath()));
|
||||||
this.eventBus.post(new FileSaveStateChangedEvent(true));
|
this.eventBus.post(new FileSaveStateChangedEvent(true));
|
||||||
@ -166,17 +160,14 @@ public class EditorController implements Initializable, Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checking if all is saved before closing the app. The user can either choose
|
|
||||||
* to exit or go back to the application and save.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
/* SUBSCRIPTIONS */
|
/* EVENT BUS LISTENERS */
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates Code Area (read from file) whenever the FileSelected is changed
|
* Updates the CodeArea whenever a new file is opened.
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
*/
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void handle(OpenFileEvent event) {
|
public void handle(OpenFileEvent event) {
|
||||||
@ -189,54 +180,96 @@ public class EditorController implements Initializable, Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save file (write to file) whenever the save in the menubare is selected
|
* Saves the editor content to a file
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
*/
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void handle(SaveFileEvent event) {
|
public void handle(SaveFileEvent event) {
|
||||||
this.saveCodeArea(event.getIsNewFile());
|
this.saveCodeArea(event.getIsNewFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refreshes the syntax highlighting when the Programming language is changed
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void handle(LanguageChangedEvent event) {
|
public void handle(LanguageChangedEvent event) {
|
||||||
this.refreshHighlighting();
|
this.refreshHighlighting();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles a comment based on the editor state
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void handle(ToggleCommentEvent event) {
|
public void handle(ToggleCommentEvent event) {
|
||||||
this.toggleComment();
|
this.toggleComment();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles the WrapText setting
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void handle(ToggleWrapTextEvent event) {
|
public void handle(ToggleWrapTextEvent event) {
|
||||||
this.setWrapText(event.getIsWrapped());
|
this.setWrapText(event.getIsWrapped());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undo if focused
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void handle(UndoEvent event) {
|
public void handle(UndoEvent event) {
|
||||||
if (this.editor.isFocused())
|
if (this.editor.isFocused())
|
||||||
this.editor.undo();
|
this.editor.undo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redo if focused
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void handle(RedoEvent event) {
|
public void handle(RedoEvent event) {
|
||||||
if (this.editor.isFocused())
|
if (this.editor.isFocused())
|
||||||
this.editor.redo();
|
this.editor.redo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy selected content if focused
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void handle(CopyEvent event) {
|
public void handle(CopyEvent event) {
|
||||||
if (this.editor.isFocused())
|
if (this.editor.isFocused())
|
||||||
this.editor.copy();
|
this.editor.copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cut selected content if focused
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void handle(CutEvent event) {
|
public void handle(CutEvent event) {
|
||||||
if (this.editor.isFocused())
|
if (this.editor.isFocused())
|
||||||
this.editor.cut();
|
this.editor.cut();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Paste from clipboard if focused
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void handle(PasteEvent event) {
|
public void handle(PasteEvent event) {
|
||||||
if (this.editor.isFocused())
|
if (this.editor.isFocused())
|
||||||
this.editor.paste();
|
this.editor.paste();
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ import app.service.FiletreeOperations;
|
|||||||
import javafx.fxml.Initializable;
|
import javafx.fxml.Initializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A FXML controller that controls the filetree component of the UI
|
* An FXML controller that controls the Filetree
|
||||||
*/
|
*/
|
||||||
public class FiletreeController implements Initializable, Controller {
|
public class FiletreeController implements Initializable, Controller {
|
||||||
|
|
||||||
@ -44,19 +44,16 @@ public class FiletreeController implements Initializable, Controller {
|
|||||||
this.eventBus.register(this);
|
this.eventBus.register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
/* FILETREE */
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The displaying of the fileTree. The inputChosen(the path) is aquired from the
|
* Generate a tree structure of a directory, and set the filetree to
|
||||||
* eventBus (OpeFileProjectEvent). The root is created as a CheckBoxItems and
|
* show the new tree
|
||||||
* sends it to generateTree, and after that setting it to the root.
|
*
|
||||||
|
* @param rootDir Path to the directory to be the root of the tree
|
||||||
*/
|
*/
|
||||||
private void showTree(String inputChosen) {
|
private void showTree(Path rootDir) {
|
||||||
CheckBoxTreeItem<String> root = new CheckBoxTreeItem<>(inputChosen);
|
CheckBoxTreeItem<String> root = new CheckBoxTreeItem<>(rootDir.getFileName().toString());
|
||||||
filetree.setShowRoot(false);
|
filetree.setShowRoot(false);
|
||||||
File fileInputChosen = new File(inputChosen);
|
File fileInputChosen = rootDir.toFile();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FiletreeOperations.generateTree(fileInputChosen, root);
|
FiletreeOperations.generateTree(fileInputChosen, root);
|
||||||
@ -67,18 +64,13 @@ public class FiletreeController implements Initializable, Controller {
|
|||||||
DialogBoxes.showErrorMessage(
|
DialogBoxes.showErrorMessage(
|
||||||
"Could not open folder.\n\n"
|
"Could not open folder.\n\n"
|
||||||
+ "Do you have the right permissions for this folder?\n"
|
+ "Do you have the right permissions for this folder?\n"
|
||||||
+ "Or does the folder contain any shortcut to somewhere within itself?");
|
+ "Or does the folder contain any shortcut to somewhere within itself?"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
/* MouseClick */
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles whenever a filetree item is clicked twice. A while loop to create the
|
* Handles opening a file whenever a filetree item is clicked twice. */
|
||||||
* correct filepath.
|
|
||||||
*/
|
|
||||||
@FXML
|
@FXML
|
||||||
private void handleMouseClick(MouseEvent event) {
|
private void handleMouseClick(MouseEvent event) {
|
||||||
if (event.getClickCount() == 2) {
|
if (event.getClickCount() == 2) {
|
||||||
@ -98,27 +90,33 @@ public class FiletreeController implements Initializable, Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
/* SUBSCRIPTIONS */
|
/* EVENT BUS LISTENERS */
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the filetree whenever a new ProjectPath is selected.
|
* Updates the filetree whenever a new project is opened
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void handle(OpenProjectEvent event) {
|
private void handle(OpenProjectEvent event) {
|
||||||
event.getPath().ifPresentOrElse(
|
event.getPath().ifPresentOrElse(
|
||||||
path -> this.showTree(path.toString()),
|
path -> this.showTree(path),
|
||||||
() -> System.err.println("[ERROR] OpenProjectEvent was empty")
|
() -> System.err.println("[ERROR] OpenProjectEvent was empty")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the filetree whenever a new file gets saved
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void handle(SaveFileEvent event) {
|
private void handle(SaveFileEvent event) {
|
||||||
if (event.getIsNewFile())
|
if (event.getIsNewFile())
|
||||||
Model
|
Model
|
||||||
.getProjectPath()
|
.getProjectPath()
|
||||||
.ifPresent(path -> this.showTree(path.toString()));
|
.ifPresent(path -> this.showTree(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -60,28 +60,25 @@ public class MenubarController implements Initializable, Controller {
|
|||||||
this.eventBus.register(this);
|
this.eventBus.register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ---------------------------------- File ---------------------------------- */
|
||||||
/* CREATE FILE/DIRECTORY */
|
|
||||||
/* ------------------------------------------------------------------------ */
|
/**
|
||||||
|
* Handles whenever the New File button is pressed in the menubar
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
@FXML
|
@FXML
|
||||||
private void handleNewFile() {
|
private void handleNewFile() {
|
||||||
this.eventBus.post(new OpenFileEvent(Optional.empty()));
|
this.eventBus.post(new OpenFileEvent(Optional.empty()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
|
||||||
private void handleNewFolder() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
/* OPEN FILE/PROJECT */
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles whenever the Open File button is pressed in the menubar
|
* Handles whenever the Open File button is pressed in the menubar
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
*/
|
*/
|
||||||
@FXML
|
@FXML
|
||||||
public void handleOpenFile() {
|
private void handleOpenFile() {
|
||||||
Stage stage = (Stage) menubar.getScene().getWindow();
|
Stage stage = (Stage) menubar.getScene().getWindow();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -95,6 +92,8 @@ public class MenubarController implements Initializable, Controller {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles whenever the Open Project button is pressed in the menubar
|
* Handles whenever the Open Project button is pressed in the menubar
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
*/
|
*/
|
||||||
@FXML
|
@FXML
|
||||||
private void handleOpenProject() {
|
private void handleOpenProject() {
|
||||||
@ -107,12 +106,11 @@ public class MenubarController implements Initializable, Controller {
|
|||||||
} catch (FileNotFoundException e) {}
|
} catch (FileNotFoundException e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
/* SAVE FILE */
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles whenever the Save button is pressed in the menubar
|
* Handles whenever the Save button is pressed in the menubar
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
*/
|
*/
|
||||||
@FXML
|
@FXML
|
||||||
private void handleSaveFile() {
|
private void handleSaveFile() {
|
||||||
@ -121,14 +119,18 @@ public class MenubarController implements Initializable, Controller {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles whenever the Save as button is pressed in the menubar
|
* Handles whenever the Save as button is pressed in the menubar
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
*/
|
*/
|
||||||
@FXML
|
@FXML
|
||||||
private void handleSaveAsFile() {
|
private void handleSaveAsFile() {
|
||||||
this.eventBus.post(new SaveFileEvent(false));
|
this.eventBus.post(new SaveFileEvent(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles whenever the programming language is changed from the menubar.
|
* Handles whenever the programming language is changed from the menubar.
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
*/
|
*/
|
||||||
@FXML
|
@FXML
|
||||||
private void handleLanguageChange(ActionEvent event) {
|
private void handleLanguageChange(ActionEvent event) {
|
||||||
@ -137,6 +139,8 @@ public class MenubarController implements Initializable, Controller {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles whenever the wraptext togglebutton is pressed in the menubar
|
* Handles whenever the wraptext togglebutton is pressed in the menubar
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
*/
|
*/
|
||||||
@FXML
|
@FXML
|
||||||
private void handleToggleWraptext(ActionEvent event) {
|
private void handleToggleWraptext(ActionEvent event) {
|
||||||
@ -146,6 +150,8 @@ public class MenubarController implements Initializable, Controller {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles whenever the theme is changed from the menubar
|
* Handles whenever the theme is changed from the menubar
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
*/
|
*/
|
||||||
@FXML
|
@FXML
|
||||||
private void handleThemeChange(ActionEvent event) {
|
private void handleThemeChange(ActionEvent event) {
|
||||||
@ -154,18 +160,20 @@ public class MenubarController implements Initializable, Controller {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles whenever the exit button is pressed in the menubar
|
* Handles whenever the exit button is pressed in the menubar
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
*/
|
*/
|
||||||
@FXML
|
@FXML
|
||||||
private void handleExitApplication(ActionEvent event) {
|
private void handleExitApplication(ActionEvent event) {
|
||||||
this.eventBus.post(new ExitApplicationEvent());
|
this.eventBus.post(new ExitApplicationEvent());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ---------------------------------- Edit ---------------------------------- */
|
||||||
/* EDIT */
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles whenever the undo button is pressed in the menubar
|
* Handles whenever the undo button is pressed in the menubar
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
*/
|
*/
|
||||||
@FXML
|
@FXML
|
||||||
private void handleUndo(ActionEvent event) {
|
private void handleUndo(ActionEvent event) {
|
||||||
@ -174,6 +182,8 @@ public class MenubarController implements Initializable, Controller {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles whenever the redo button is pressed in the menubar
|
* Handles whenever the redo button is pressed in the menubar
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
*/
|
*/
|
||||||
@FXML
|
@FXML
|
||||||
private void handleRedo(ActionEvent event) {
|
private void handleRedo(ActionEvent event) {
|
||||||
@ -182,6 +192,8 @@ public class MenubarController implements Initializable, Controller {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles whenever the copy button is pressed in the menubar
|
* Handles whenever the copy button is pressed in the menubar
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
*/
|
*/
|
||||||
@FXML
|
@FXML
|
||||||
private void handleCopy(ActionEvent event) {
|
private void handleCopy(ActionEvent event) {
|
||||||
@ -190,6 +202,8 @@ public class MenubarController implements Initializable, Controller {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles whenever the cut button is pressed in the menubar
|
* Handles whenever the cut button is pressed in the menubar
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
*/
|
*/
|
||||||
@FXML
|
@FXML
|
||||||
private void handleCut(ActionEvent event) {
|
private void handleCut(ActionEvent event) {
|
||||||
@ -198,6 +212,8 @@ public class MenubarController implements Initializable, Controller {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles whenever the paste button is pressed in the menubar
|
* Handles whenever the paste button is pressed in the menubar
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
*/
|
*/
|
||||||
@FXML
|
@FXML
|
||||||
private void handlePaste(ActionEvent event) {
|
private void handlePaste(ActionEvent event) {
|
||||||
@ -206,18 +222,20 @@ public class MenubarController implements Initializable, Controller {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles whenever the Toggle Comment button is pressed in the menubar
|
* Handles whenever the Toggle Comment button is pressed in the menubar
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
*/
|
*/
|
||||||
@FXML
|
@FXML
|
||||||
private void handleToggleComment(ActionEvent event) {
|
private void handleToggleComment(ActionEvent event) {
|
||||||
this.eventBus.post(new ToggleCommentEvent());
|
this.eventBus.post(new ToggleCommentEvent());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
/* ---------------------------------- About --------------------------------- */
|
||||||
/* ABOUT */
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles whenever the About button is pressed in the menubar
|
* Handles whenever the About button is pressed in the menubar
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
*/
|
*/
|
||||||
@FXML
|
@FXML
|
||||||
private void handleAbout(ActionEvent event) {
|
private void handleAbout(ActionEvent event) {
|
||||||
@ -231,22 +249,37 @@ public class MenubarController implements Initializable, Controller {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates menubuttons whenever the language is changed
|
* Updates menubuttons whenever the language is changed
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
*/
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void handle(LanguageChangedEvent event) {
|
public void handle(LanguageChangedEvent event) {
|
||||||
this.languageToggleGroup.getToggles().stream().map(RadioMenuItem.class::cast)
|
this.languageToggleGroup
|
||||||
.filter(t -> t.getId().equals("toggle" + event.getLanguage())).findFirst().orElseThrow().setSelected(true);
|
.getToggles()
|
||||||
|
.stream()
|
||||||
|
.map(RadioMenuItem.class::cast)
|
||||||
|
.filter(t -> t.getId().equals("toggle" + event.getLanguage()))
|
||||||
|
.findFirst()
|
||||||
|
// This should never happen!
|
||||||
|
.orElseThrow(() -> new IllegalStateException("Language button missing: " + event.getLanguage()))
|
||||||
|
.setSelected(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates menubuttons whenever the theme is changed
|
* Updates menubuttons whenever the theme is changed
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void handle(ThemeChangedEvent event) {
|
public void handle(ThemeChangedEvent event) {
|
||||||
this.themeToggleGroup.getToggles().stream().map(RadioMenuItem.class::cast)
|
this.themeToggleGroup
|
||||||
.filter(t -> t.getId().equals("toggle" + event.getTheme().replace(" ", "_"))).findFirst().orElseThrow().setSelected(true);
|
.getToggles()
|
||||||
|
.stream()
|
||||||
|
.map(RadioMenuItem.class::cast)
|
||||||
|
.filter(t -> t.getId().equals("toggle" + event.getTheme().replace(" ", "_")))
|
||||||
|
.findFirst()
|
||||||
|
// This should never happen!
|
||||||
|
.orElseThrow(() -> new IllegalStateException("Theme button missing: " + event.getTheme()))
|
||||||
|
.setSelected(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -53,34 +53,48 @@ public class ModelineController implements Initializable, Controller {
|
|||||||
this.columnrow.setText(String.format("[%d:%d]", row, column));
|
this.columnrow.setText(String.format("[%d:%d]", row, column));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
/* SUBSCRIPTIONS */
|
||||||
|
/* ------------------------------------------------------------------------ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the column-row number display whenever the editor cursor
|
* Updates the column-row number display whenever the editor cursor
|
||||||
* changes position.
|
* changes position.
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
*/
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void handle(EditorChangedEvent event) {
|
public void handle(EditorChangedEvent event) {
|
||||||
this.setColumnRow(event.getColumn(), event.getLine());
|
this.setColumnRow(event.getColumn(), event.getLine());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the saveState label whenever the file either is saved or modified
|
* Updates the saveState label whenever the file either is saved or modified
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
*/
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void handle(FileSaveStateChangedEvent event) {
|
public void handle(FileSaveStateChangedEvent event) {
|
||||||
// TODO: Add CSS styleclass for coloring the saveState label
|
// TODO: Add CSS styleclass for coloring the saveState label
|
||||||
// whenever it changes
|
// whenever it changes
|
||||||
this.saveState.setText(event.getIsSaved() ? "Saved!" : "Modified");
|
this.saveState.setText(event.getIsSaved() ? "Saved!" : "Modified");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the modeline to display a new language
|
* Updates the modeline to display a new language when changed.
|
||||||
* whenever it is changed.
|
*
|
||||||
|
* @param event
|
||||||
*/
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void handle(LanguageChangedEvent event) {
|
private void handle(LanguageChangedEvent event) {
|
||||||
this.language.setText(event.getLanguage());
|
this.language.setText(event.getLanguage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the modeline to display the name of the current file when changed
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void handle(OpenFileEvent event) {
|
private void handle(OpenFileEvent event) {
|
||||||
this.filename.setText(
|
this.filename.setText(
|
||||||
|
@ -5,22 +5,21 @@ import java.util.regex.Pattern;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* An interface describing functions required for a class to
|
* An interface describing functions required for a class to
|
||||||
* provide language specific details and functionality to the
|
* provide language specific details and functionality.
|
||||||
* editor
|
|
||||||
*/
|
*/
|
||||||
public interface ProgrammingLanguage {
|
public interface ProgrammingLanguage {
|
||||||
/**
|
/**
|
||||||
* The name of the programming language
|
* @return The name of the programming language
|
||||||
*/
|
*/
|
||||||
public String getName();
|
public String getName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The map containing the regex and corresponding style-classes to be used for syntax highlighting
|
* @return The map containing the regexes and corresponding style-classes to be used for syntax highlighting
|
||||||
*/
|
*/
|
||||||
public Map<Pattern,String> getPatternMap();
|
public Map<Pattern,String> getPatternMap();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The pattern containing all regexes for syntax highlighting
|
* @return A combined regex for syntax highlighting
|
||||||
*/
|
*/
|
||||||
public Pattern getPattern();
|
public Pattern getPattern();
|
||||||
|
|
||||||
@ -39,8 +38,8 @@ public interface ProgrammingLanguage {
|
|||||||
public String unCommentLine(String line);
|
public String unCommentLine(String line);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not a line is commented
|
|
||||||
* @param line The text of the line
|
* @param line The text of the line
|
||||||
|
* @return Whether or not a line is commented
|
||||||
*/
|
*/
|
||||||
public boolean isCommentedLine(String line);
|
public boolean isCommentedLine(String line);
|
||||||
|
|
||||||
@ -52,15 +51,15 @@ public interface ProgrammingLanguage {
|
|||||||
public String commentSelection(String selection);
|
public String commentSelection(String selection);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uncomment a line
|
* Uncomment an area of text
|
||||||
* @param selection The text of the line to uncomment
|
* @param selection The text of the area to uncomment
|
||||||
* @return The uncommented area
|
* @return The uncommented area
|
||||||
*/
|
*/
|
||||||
public String unCommentSelection(String selection);
|
public String unCommentSelection(String selection);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not an area of text is commented
|
|
||||||
* @param selection The content of the area
|
* @param selection The content of the area
|
||||||
|
* @return Whether or not an area of text is commented
|
||||||
*/
|
*/
|
||||||
public boolean isCommentedSelection(String selection);
|
public boolean isCommentedSelection(String selection);
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ import app.model.ProgrammingLanguage;
|
|||||||
public class Java implements ProgrammingLanguage {
|
public class Java implements ProgrammingLanguage {
|
||||||
|
|
||||||
private String name = "Java";
|
private String name = "Java";
|
||||||
|
private static Map<Pattern, String> pattern;
|
||||||
|
|
||||||
private static final String[] keywords = new String[] {
|
private static final String[] keywords = new String[] {
|
||||||
"abstract", "assert", "boolean", "break", "byte",
|
"abstract", "assert", "boolean", "break", "byte",
|
||||||
@ -52,9 +53,11 @@ public class Java implements ProgrammingLanguage {
|
|||||||
e("(?://.*)|/\\*(?:\\n|.)*?\\*/", "comment")
|
e("(?://.*)|/\\*(?:\\n|.)*?\\*/", "comment")
|
||||||
);
|
);
|
||||||
|
|
||||||
private static Map<Pattern, String> pattern;
|
|
||||||
|
|
||||||
public Java() {
|
public Java() {
|
||||||
|
this.initializePatternMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializePatternMap() {
|
||||||
pattern = new LinkedHashMap<>();
|
pattern = new LinkedHashMap<>();
|
||||||
patternList
|
patternList
|
||||||
.forEach(e -> pattern.put(e.getKey(), e.getValue()));
|
.forEach(e -> pattern.put(e.getKey(), e.getValue()));
|
||||||
|
@ -14,6 +14,7 @@ import app.model.ProgrammingLanguage;
|
|||||||
public class Markdown implements ProgrammingLanguage {
|
public class Markdown implements ProgrammingLanguage {
|
||||||
|
|
||||||
private String name = "Markdown";
|
private String name = "Markdown";
|
||||||
|
private static Map<Pattern, String> pattern;
|
||||||
|
|
||||||
private static Entry<Pattern, String> e(String k, String v) {
|
private static Entry<Pattern, String> e(String k, String v) {
|
||||||
return new AbstractMap.SimpleEntry<>(Pattern.compile(k), v);
|
return new AbstractMap.SimpleEntry<>(Pattern.compile(k), v);
|
||||||
@ -38,9 +39,12 @@ public class Markdown implements ProgrammingLanguage {
|
|||||||
e("\\[\\d+\\]: .*", "source")
|
e("\\[\\d+\\]: .*", "source")
|
||||||
);
|
);
|
||||||
|
|
||||||
private static Map<Pattern, String> pattern;
|
|
||||||
|
|
||||||
public Markdown() {
|
public Markdown() {
|
||||||
|
this.initializePatternMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializePatternMap() {
|
||||||
pattern = new LinkedHashMap<>();
|
pattern = new LinkedHashMap<>();
|
||||||
patternList
|
patternList
|
||||||
.forEach(e -> pattern.put(e.getKey(), e.getValue()));
|
.forEach(e -> pattern.put(e.getKey(), e.getValue()));
|
||||||
|
@ -1,16 +1,51 @@
|
|||||||
package app.service;
|
package app.service;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import app.model.Model;
|
||||||
import javafx.scene.control.Alert;
|
import javafx.scene.control.Alert;
|
||||||
import javafx.scene.control.Alert.AlertType;
|
import javafx.scene.control.Alert.AlertType;
|
||||||
|
import javafx.stage.DirectoryChooser;
|
||||||
|
import javafx.stage.FileChooser;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
public class DialogBoxes {
|
public class DialogBoxes {
|
||||||
|
|
||||||
private DialogBoxes() {}
|
private DialogBoxes() {}
|
||||||
|
private static FileChooser fc = new FileChooser();
|
||||||
|
private static DirectoryChooser dc = new DirectoryChooser();
|
||||||
|
private static Alert error = new Alert(AlertType.ERROR);
|
||||||
|
|
||||||
public static void showErrorMessage(String errorMessage) {
|
public static void showErrorMessage(String errorMessage) {
|
||||||
Alert error = new Alert(AlertType.ERROR);
|
|
||||||
error.setContentText(errorMessage);
|
error.setContentText(errorMessage);
|
||||||
error.showAndWait();
|
error.showAndWait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static File showopenFileWithDialog(Stage stage) {
|
||||||
|
fc.setTitle("Open File");
|
||||||
|
File chosenFile = fc.showOpenDialog(stage);
|
||||||
|
|
||||||
|
return chosenFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File showOpenFolderWithDialog(Stage stage) {
|
||||||
|
dc.setTitle("Open Project");
|
||||||
|
File dir = dc.showDialog(stage);
|
||||||
|
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File showSaveFileWithDialog(Stage stage) {
|
||||||
|
FileChooser fc = new FileChooser();
|
||||||
|
fc.setTitle("Save as");
|
||||||
|
|
||||||
|
Model
|
||||||
|
.getProjectPath()
|
||||||
|
.ifPresent(path -> fc.setInitialDirectory(path.toFile()));
|
||||||
|
|
||||||
|
File chosenLocation = fc.showSaveDialog(stage);
|
||||||
|
|
||||||
|
return chosenLocation;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,11 @@ import java.io.File;
|
|||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
import app.model.Model;
|
import app.model.Model;
|
||||||
import javafx.stage.DirectoryChooser;
|
|
||||||
import javafx.stage.FileChooser;
|
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
public class FileOperations {
|
public class FileOperations {
|
||||||
@ -20,11 +19,7 @@ public class FileOperations {
|
|||||||
// TODO: This class needs to be extensively error checked
|
// TODO: This class needs to be extensively error checked
|
||||||
|
|
||||||
public static File openFileWithDialog(Stage stage) throws FileNotFoundException {
|
public static File openFileWithDialog(Stage stage) throws FileNotFoundException {
|
||||||
|
File chosenFile = DialogBoxes.showopenFileWithDialog(stage);
|
||||||
FileChooser fc = new FileChooser();
|
|
||||||
fc.setTitle("Open File");
|
|
||||||
|
|
||||||
File chosenFile = fc.showOpenDialog(stage);
|
|
||||||
|
|
||||||
if (chosenFile == null)
|
if (chosenFile == null)
|
||||||
throw new FileNotFoundException();
|
throw new FileNotFoundException();
|
||||||
@ -34,11 +29,7 @@ public class FileOperations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static File openFolderWithDialog(Stage stage) throws FileNotFoundException {
|
public static File openFolderWithDialog(Stage stage) throws FileNotFoundException {
|
||||||
|
File dir = DialogBoxes.showOpenFolderWithDialog(stage);
|
||||||
DirectoryChooser dc = new DirectoryChooser();
|
|
||||||
dc.setTitle("Open Project");
|
|
||||||
|
|
||||||
File dir = dc.showDialog(stage);
|
|
||||||
|
|
||||||
if (dir == null)
|
if (dir == null)
|
||||||
throw new FileNotFoundException();
|
throw new FileNotFoundException();
|
||||||
@ -58,16 +49,15 @@ public class FileOperations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean saveFileWithDialog(Stage stage, String content) {
|
public static boolean saveFileWithDialog(Stage stage, String content) {
|
||||||
FileChooser fc = new FileChooser();
|
File chosenLocation;
|
||||||
fc.setTitle("Save as");
|
|
||||||
|
|
||||||
Model
|
try {
|
||||||
.getProjectPath()
|
chosenLocation = DialogBoxes.showSaveFileWithDialog(stage);
|
||||||
.ifPresent(path -> fc.setInitialDirectory(path.toFile()));
|
} catch (NoSuchElementException e) {
|
||||||
|
|
||||||
File chosenLocation = fc.showSaveDialog(stage);
|
|
||||||
if (chosenLocation == null)
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chosenLocation == null) return false;
|
||||||
|
|
||||||
if (saveFile(chosenLocation.toPath(), content)) {
|
if (saveFile(chosenLocation.toPath(), content)) {
|
||||||
Model.setActiveFilePath(Optional.of(chosenLocation.toPath()));
|
Model.setActiveFilePath(Optional.of(chosenLocation.toPath()));
|
||||||
|
@ -17,15 +17,21 @@ import app.model.Model;
|
|||||||
|
|
||||||
public class SettingsProvider implements SettingsProviderI {
|
public class SettingsProvider implements SettingsProviderI {
|
||||||
|
|
||||||
private static EventBus eventBus;
|
private EventBus eventBus;
|
||||||
|
|
||||||
private static final String SETTINGS_PATH =
|
private String settingsPath =
|
||||||
(System.getProperty("os.name").startsWith("Windows"))
|
(System.getProperty("os.name").startsWith("Windows"))
|
||||||
? System.getProperty("user.home") + "\\AppData\\Roaming\\/BNNsettings.dat"
|
? System.getProperty("user.home") + "\\AppData\\Roaming\\/BNNsettings.dat"
|
||||||
: System.getProperty("user.home") + System.getProperty("file.separator") + ".BNNsettings.dat";
|
: System.getProperty("user.home") + System.getProperty("file.separator") + ".BNNsettings.dat";
|
||||||
|
|
||||||
private static List<String> legalSettings =
|
private List<String> legalSettings =
|
||||||
Arrays.asList("Java", "Markdown", "Monokai", "Solarized Light");
|
Arrays.asList("Java", "Markdown", "Monokai", "Solarized Light");
|
||||||
|
|
||||||
|
|
||||||
|
// Only for testing purposes
|
||||||
|
protected void setSettingsPath(String settingsPath) {
|
||||||
|
this.settingsPath = settingsPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public SettingsProvider(EventBus eB) {
|
public SettingsProvider(EventBus eB) {
|
||||||
@ -35,13 +41,13 @@ public class SettingsProvider implements SettingsProviderI {
|
|||||||
|
|
||||||
public void setEventBus(EventBus eB) {
|
public void setEventBus(EventBus eB) {
|
||||||
eventBus = eB;
|
eventBus = eB;
|
||||||
SettingsProvider.eventBus.register(this);
|
eventBus.register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadSettings() {
|
public void loadSettings() {
|
||||||
List<String> settings = new ArrayList<>();
|
List<String> settings = new ArrayList<>();
|
||||||
try (Scanner sc = new Scanner(new File(SETTINGS_PATH))) {
|
try (Scanner sc = new Scanner(new File(settingsPath))) {
|
||||||
|
|
||||||
while (sc.hasNextLine()) {
|
while (sc.hasNextLine()) {
|
||||||
var nextLine = sc.nextLine().trim();
|
var nextLine = sc.nextLine().trim();
|
||||||
@ -69,7 +75,7 @@ public class SettingsProvider implements SettingsProviderI {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveSettings() {
|
public void saveSettings() {
|
||||||
try (PrintWriter writer = new PrintWriter(new File(SETTINGS_PATH))) {
|
try (PrintWriter writer = new PrintWriter(new File(settingsPath))) {
|
||||||
writer.println("- Settings:");
|
writer.println("- Settings:");
|
||||||
writer.println("Programming Language = " + Model.getLanguage().getName());
|
writer.println("Programming Language = " + Model.getLanguage().getName());
|
||||||
writer.println("Theme = " + Model.getTheme());
|
writer.println("Theme = " + Model.getTheme());
|
||||||
|
@ -2,8 +2,14 @@ package app.settings;
|
|||||||
|
|
||||||
public interface SettingsProviderI {
|
public interface SettingsProviderI {
|
||||||
|
|
||||||
void loadSettings();
|
/**
|
||||||
|
* Load settings from disk, and fire events to update the program state
|
||||||
|
*/
|
||||||
|
void loadSettings();
|
||||||
|
|
||||||
void saveSettings();
|
/**
|
||||||
|
* Save the state from {@link app.model.Model Model} to disk.
|
||||||
|
*/
|
||||||
|
void saveSettings();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
<Menu mnemonicParsing="false" text="File">
|
<Menu mnemonicParsing="false" text="File">
|
||||||
<items>
|
<items>
|
||||||
<MenuItem mnemonicParsing="false" text="New File" accelerator="Shortcut+n" onAction="#handleNewFile"/>
|
<MenuItem mnemonicParsing="false" text="New File" accelerator="Shortcut+n" onAction="#handleNewFile"/>
|
||||||
<MenuItem mnemonicParsing="false" text="New Folder" accelerator="Shortcut+Shift+N" onAction="#handleNewFolder"/>
|
|
||||||
<SeparatorMenuItem/>
|
<SeparatorMenuItem/>
|
||||||
<MenuItem mnemonicParsing="false" text="Open File" accelerator="Shortcut+o" onAction="#handleOpenFile"/>
|
<MenuItem mnemonicParsing="false" text="Open File" accelerator="Shortcut+o" onAction="#handleOpenFile"/>
|
||||||
<MenuItem mnemonicParsing="false" text="Open Project" accelerator="Shortcut+Shift+O" onAction="#handleOpenProject"/>
|
<MenuItem mnemonicParsing="false" text="Open Project" accelerator="Shortcut+Shift+O" onAction="#handleOpenProject"/>
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
package app;
|
|
||||||
|
|
||||||
import javafx.scene.Node;
|
|
||||||
import javafx.stage.Stage;
|
|
||||||
import org.junit.jupiter.api.AfterEach;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.testfx.api.FxToolkit;
|
|
||||||
import org.testfx.framework.junit5.ApplicationTest;
|
|
||||||
import org.testfx.util.WaitForAsyncUtils;
|
|
||||||
|
|
||||||
import java.util.concurrent.TimeoutException;
|
|
||||||
|
|
||||||
public class FxTestTemplate extends ApplicationTest {
|
|
||||||
|
|
||||||
private Stage stage;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
public void runAppToTests() throws Exception {
|
|
||||||
FxToolkit.registerPrimaryStage();
|
|
||||||
FxToolkit.setupApplication(Main::new);
|
|
||||||
FxToolkit.showStage();
|
|
||||||
WaitForAsyncUtils.waitForFxEvents(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterEach
|
|
||||||
public void stopApp() throws TimeoutException {
|
|
||||||
FxToolkit.cleanupStages();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void start(Stage primaryStage){
|
|
||||||
this.stage = primaryStage;
|
|
||||||
primaryStage.toFront();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Stage getStage() {
|
|
||||||
return stage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T extends Node> T find(final String query) {
|
|
||||||
/** TestFX provides many operations to retrieve elements from the loaded GUI. */
|
|
||||||
return lookup(query).query();
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,6 +2,7 @@ package app.controllers;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Paths;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.fxmisc.richtext.CodeArea;
|
import org.fxmisc.richtext.CodeArea;
|
||||||
@ -19,7 +20,6 @@ import static org.mockito.ArgumentMatchers.anyInt;
|
|||||||
import static org.mockito.ArgumentMatchers.anyString;
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.mockStatic;
|
import static org.mockito.Mockito.mockStatic;
|
||||||
import static org.mockito.Mockito.never;
|
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
@ -63,7 +63,7 @@ public class EditorControllerTest extends FxTestTemplate {
|
|||||||
|
|
||||||
private String mockContent = """
|
private String mockContent = """
|
||||||
class HelloWorld {
|
class HelloWorld {
|
||||||
private String message = "Hello world";
|
private String message = \"Hello world\";
|
||||||
|
|
||||||
public String getMessage() {
|
public String getMessage() {
|
||||||
return message;
|
return message;
|
||||||
@ -100,11 +100,15 @@ public class EditorControllerTest extends FxTestTemplate {
|
|||||||
@Test
|
@Test
|
||||||
@DisplayName("Test handling of OpenFileEvent with a file that doesn't exist")
|
@DisplayName("Test handling of OpenFileEvent with a file that doesn't exist")
|
||||||
public void testOpenFileEventWithUnrealFile() throws IOException {
|
public void testOpenFileEventWithUnrealFile() throws IOException {
|
||||||
|
try (MockedStatic<FileOperations> mocked = mockStatic(FileOperations.class)) {
|
||||||
|
mocked.when(() -> FileOperations.readFile(any()))
|
||||||
|
.thenReturn(null);
|
||||||
|
|
||||||
String brokenFilePath = "/doesNotExist.txt";
|
String brokenFilePath = "/doesNotExist.txt";
|
||||||
eventBus.post(new OpenFileEvent(Optional.ofNullable(new File(brokenFilePath).toPath())));
|
eventBus.post(new OpenFileEvent(Optional.ofNullable(Paths.get(brokenFilePath))));
|
||||||
|
|
||||||
verify(editor, never()).clear();
|
verify(editor).appendText("");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
8
src/test/java/app/service/DialogBoxesTest.java
Normal file
8
src/test/java/app/service/DialogBoxesTest.java
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package app.service;
|
||||||
|
|
||||||
|
public class DialogBoxesTest {
|
||||||
|
|
||||||
|
// THIS CLASS COULD NOT BE UNITTESTED BECAUSE OF LACKING SUPPORT FOR MOCKING
|
||||||
|
// STATIC OBJECTS WITH MOCKITO AND JUNI5
|
||||||
|
|
||||||
|
}
|
190
src/test/java/app/service/FileOperationsTest.java
Normal file
190
src/test/java/app/service/FileOperationsTest.java
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
package app.service;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.mockStatic;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.common.io.Files;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.junit.jupiter.api.io.TempDir;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockedStatic;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
import app.model.Model;
|
||||||
|
import javafx.scene.control.Alert;
|
||||||
|
import javafx.stage.DirectoryChooser;
|
||||||
|
import javafx.stage.FileChooser;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
public class FileOperationsTest {
|
||||||
|
|
||||||
|
// THIS CLASS COULD NOT BE UNITTESTED BECAUSE OF LACKING SUPPORT FOR MOCKING
|
||||||
|
// STATIC OBJECTS WITH MOCKITO AND JUNI5
|
||||||
|
|
||||||
|
// @TempDir
|
||||||
|
// File tmp;
|
||||||
|
|
||||||
|
// @Mock
|
||||||
|
// FileChooser fc = mock(FileChooser.class);
|
||||||
|
|
||||||
|
// @Mock
|
||||||
|
// DirectoryChooser dc = mock(DirectoryChooser.class);
|
||||||
|
|
||||||
|
// @Mock
|
||||||
|
// Alert error = mock(Alert.class);
|
||||||
|
|
||||||
|
// @InjectMocks
|
||||||
|
// MockedStatic<DialogBoxes> db = mockStatic(DialogBoxes.class);
|
||||||
|
|
||||||
|
// @Test
|
||||||
|
// @DisplayName("Test openFileWithDialog")
|
||||||
|
// public void testOpenFileWithDialog() {
|
||||||
|
// // try (MockedStatic<DialogBoxes> mocked = mockStatic(DialogBoxes.class)) {
|
||||||
|
// Stage stage = mock(Stage.class);
|
||||||
|
|
||||||
|
// db.when(() -> DialogBoxes.showopenFileWithDialog(any()))
|
||||||
|
// .thenReturn(null);
|
||||||
|
// assertThrows(FileNotFoundException.class, () -> FileOperations.openFileWithDialog(stage));
|
||||||
|
|
||||||
|
// File file = mock(File.class);
|
||||||
|
// db.when(() -> DialogBoxes.showopenFileWithDialog(any()))
|
||||||
|
// .thenReturn(file);
|
||||||
|
// try {
|
||||||
|
// assertEquals(file, FileOperations.openFileWithDialog(stage));
|
||||||
|
// } catch (FileNotFoundException e) {
|
||||||
|
// fail("Chosen file was null when it was expected to be mock file");
|
||||||
|
// }
|
||||||
|
// // }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// @Test
|
||||||
|
// @DisplayName("Test openFolderWithDialog")
|
||||||
|
// public void testOpenFolderWithDialog() {
|
||||||
|
// try (MockedStatic<DialogBoxes> mocked = mockStatic(DialogBoxes.class)) {
|
||||||
|
// Stage stage = mock(Stage.class);
|
||||||
|
|
||||||
|
// mocked.when(() -> DialogBoxes.showOpenFolderWithDialog(any()))
|
||||||
|
// .thenReturn(null);
|
||||||
|
// assertThrows(FileNotFoundException.class, () -> FileOperations.openFolderWithDialog(stage));
|
||||||
|
|
||||||
|
// File file = mock(File.class);
|
||||||
|
// mocked.when(() -> DialogBoxes.showOpenFolderWithDialog(any()))
|
||||||
|
// .thenReturn(file);
|
||||||
|
// try {
|
||||||
|
// assertEquals(file, FileOperations.openFolderWithDialog(stage));
|
||||||
|
// } catch (FileNotFoundException e) {
|
||||||
|
// fail("Chosen file was null when it was expected to be mock file");
|
||||||
|
// }
|
||||||
|
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private File createTemporaryFile() throws IOException {
|
||||||
|
// File f = new File(tmp, "test.txt");
|
||||||
|
// f.createNewFile();
|
||||||
|
// return f;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @Test
|
||||||
|
// @DisplayName("Test saveFile")
|
||||||
|
// public void testSaveFile() {
|
||||||
|
// String content = "test\ncontent\nfor\nyou";
|
||||||
|
// File f;
|
||||||
|
|
||||||
|
// try (MockedStatic<DialogBoxes> mocked = mockStatic(DialogBoxes.class)) {
|
||||||
|
// // mocked.when(() -> DialogBoxes.showErrorMessage(anyString()));
|
||||||
|
|
||||||
|
// f = createTemporaryFile();
|
||||||
|
// assertTrue(FileOperations.saveFile(f.toPath(), content));
|
||||||
|
|
||||||
|
// List<String> read = Files.readLines(f, StandardCharsets.UTF_8);
|
||||||
|
// String value = String.join("\n", read);
|
||||||
|
// assertEquals(content, value);
|
||||||
|
|
||||||
|
// Path wrongPath = Paths.get("wrongPath.txt");
|
||||||
|
// assertFalse(FileOperations.saveFile(wrongPath, content));
|
||||||
|
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// fail("Unexpected temporary file failure");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @Test
|
||||||
|
// @DisplayName("Test saveFileWithDialog")
|
||||||
|
// public void testSaveFileWithDialog() {
|
||||||
|
// String content = "test\ncontent\nfor\nyou";
|
||||||
|
// File f;
|
||||||
|
|
||||||
|
// try (MockedStatic<DialogBoxes> mocked = mockStatic(DialogBoxes.class)) {
|
||||||
|
// Stage stage = mock(Stage.class);
|
||||||
|
|
||||||
|
// mocked.when(() -> DialogBoxes.showSaveFileWithDialog(any()))
|
||||||
|
// .thenReturn(false);
|
||||||
|
// assertFalse(FileOperations.saveFileWithDialog(stage, content));
|
||||||
|
|
||||||
|
// mocked.when(() -> DialogBoxes.showSaveFileWithDialog(any()))
|
||||||
|
// .thenReturn(null);
|
||||||
|
// assertFalse(FileOperations.saveFileWithDialog(stage, content));
|
||||||
|
|
||||||
|
// f = createTemporaryFile();
|
||||||
|
// mocked.when(() -> DialogBoxes.showSaveFileWithDialog(any()))
|
||||||
|
// .thenReturn(f);
|
||||||
|
// assertTrue(FileOperations.saveFileWithDialog(stage, content));
|
||||||
|
// assertEquals(Model.getActiveFilePath(), f.toPath());
|
||||||
|
|
||||||
|
// File wrongFile = new File("Does not exist");
|
||||||
|
// mocked.when(() -> DialogBoxes.showSaveFileWithDialog(any()))
|
||||||
|
// .thenReturn(wrongFile);
|
||||||
|
// assertFalse(FileOperations.saveFileWithDialog(stage, content));
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// fail("Unexpected IOexception when creating temporary file");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @Test
|
||||||
|
// @DisplayName("Test readFile")
|
||||||
|
// public void testReadFile() {
|
||||||
|
// File f;
|
||||||
|
|
||||||
|
// try (MockedStatic<DialogBoxes> mocked = mockStatic(DialogBoxes.class)) {
|
||||||
|
// // mocked.when(() -> DialogBoxes.showErrorMessage(anyString()));
|
||||||
|
|
||||||
|
// assertEquals("", FileOperations.readFile(null));
|
||||||
|
|
||||||
|
// String content = "test\ncontent\nfor\nyou";
|
||||||
|
// f = createTemporaryFile();
|
||||||
|
|
||||||
|
// Files.write(content.getBytes(), f);
|
||||||
|
|
||||||
|
// assertEquals(content, FileOperations.readFile(f.toPath()));
|
||||||
|
|
||||||
|
// Path wrongPath = Paths.get("wrongPath.txt");
|
||||||
|
// assertThrows(FileNotFoundException.class, () -> FileOperations.readFile(wrongPath));
|
||||||
|
|
||||||
|
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// fail("Unexpected temporary file failure");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
108
src/test/java/app/settings/SettingsProviderTest.java
Normal file
108
src/test/java/app/settings/SettingsProviderTest.java
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
package app.settings;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.nio.file.StandardOpenOption;
|
||||||
|
|
||||||
|
import com.google.common.eventbus.EventBus;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.DisplayName;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.junit.jupiter.api.io.TempDir;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
import app.model.Model;
|
||||||
|
import app.model.languages.Java;
|
||||||
|
import app.model.languages.Markdown;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
public class SettingsProviderTest {
|
||||||
|
|
||||||
|
@TempDir
|
||||||
|
File tmp;
|
||||||
|
|
||||||
|
private EventBus eventBus = new EventBus();
|
||||||
|
|
||||||
|
private SettingsProvider sp = new SettingsProvider(eventBus);
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
private void initializeSettingsPath() {
|
||||||
|
sp.setSettingsPath(Paths.get(tmp.toPath().toString(), "BNNsettings.dat").toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Test loadSettings with pre-existing settings file")
|
||||||
|
public void testLoadSettings() throws IOException {
|
||||||
|
File f = new File(tmp, "BNNsettings.dat");
|
||||||
|
f.createNewFile();
|
||||||
|
|
||||||
|
Files.writeString(
|
||||||
|
f.toPath(),
|
||||||
|
"- Settings:\n"
|
||||||
|
+ "Programming Language = Markdown\n"
|
||||||
|
+ "Theme = Solarized Light",
|
||||||
|
StandardOpenOption.WRITE
|
||||||
|
);
|
||||||
|
|
||||||
|
sp.loadSettings();
|
||||||
|
assertTrue(Model.getLanguage() instanceof Markdown);
|
||||||
|
assertEquals("Solarized Light", Model.getTheme());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Test loadSettings without pre-existing settings file")
|
||||||
|
public void testLoadSettingsWithoutFile() throws IOException {
|
||||||
|
|
||||||
|
sp.loadSettings();
|
||||||
|
assertTrue(Model.getLanguage() instanceof Java);
|
||||||
|
assertEquals("Monokai", Model.getTheme());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Test loadSettings with broken settings file")
|
||||||
|
public void testLoadSettingsWithErrorFile() throws IOException {
|
||||||
|
File f = new File(tmp, "BNNsettings.dat");
|
||||||
|
f.createNewFile();
|
||||||
|
|
||||||
|
Files.writeString(
|
||||||
|
f.toPath(),
|
||||||
|
"- Settings:\n"
|
||||||
|
+ "Programming Language = Nonexisting Language\n"
|
||||||
|
+ "Theme = Solarized Light",
|
||||||
|
StandardOpenOption.WRITE
|
||||||
|
);
|
||||||
|
|
||||||
|
sp.loadSettings();
|
||||||
|
assertTrue(Model.getLanguage() instanceof Java);
|
||||||
|
assertEquals("Monokai", Model.getTheme());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("Test save settings")
|
||||||
|
public void testSaveSettings() {
|
||||||
|
Model.setLanguage(new Markdown());
|
||||||
|
Model.setTheme("Solarized Light");
|
||||||
|
|
||||||
|
sp.saveSettings();
|
||||||
|
|
||||||
|
try {
|
||||||
|
assertEquals(
|
||||||
|
"- Settings:\n"
|
||||||
|
+ "Programming Language = Markdown\n"
|
||||||
|
+ "Theme = Solarized Light\n",
|
||||||
|
Files.readString(Paths.get(tmp.toString(), "BNNsettings.dat"))
|
||||||
|
);
|
||||||
|
} catch (IOException e) {
|
||||||
|
fail("Couldn't read settings file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user