Merge branch 'extract-file-operations' into 'master'
Extract logic from classes See merge request oysteikt/h20-tdt4100-project!6
This commit is contained in:
commit
59a45ba4a5
@ -1,17 +1,13 @@
|
||||
package app.controllers;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collection;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Scanner;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import org.apache.commons.lang.ObjectUtils.Null;
|
||||
import org.fxmisc.richtext.CodeArea;
|
||||
import org.fxmisc.richtext.LineNumberFactory;
|
||||
import org.fxmisc.richtext.model.StyleSpans;
|
||||
@ -23,26 +19,26 @@ import app.events.CutEvent;
|
||||
import app.events.EditorChangedEvent;
|
||||
|
||||
import app.events.LanguageChangedEvent;
|
||||
import app.events.OpenFileEvent;
|
||||
import app.events.PasteEvent;
|
||||
import app.events.RedoEvent;
|
||||
import app.events.SaveFileEvent;
|
||||
import app.events.ToggleCommentEvent;
|
||||
import app.events.ToggleWrapTextEvent;
|
||||
import app.events.UndoEvent;
|
||||
import app.interfaces.FileManagement;
|
||||
import app.events.FileSaveStateChangedEvent;
|
||||
import app.events.FileSelectedEvent;
|
||||
import app.model.Model;
|
||||
import app.service.FileOperations;
|
||||
import app.service.LanguageOperations;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Alert.AlertType;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
* A FXML controller that controls the editor component of the UI
|
||||
*/
|
||||
public class EditorController implements Initializable, Controller, FileManagement {
|
||||
public class EditorController implements Initializable, Controller {
|
||||
|
||||
@FXML
|
||||
private CodeArea editor;
|
||||
@ -96,6 +92,7 @@ public class EditorController implements Initializable, Controller, FileManageme
|
||||
* ProgrammingLanguage.commentLine(line)
|
||||
*/
|
||||
private void toggleComment() {
|
||||
// TODO: This logic might need to be moved to LanguageOperations
|
||||
if (editor.getSelectedText().equals("")) {
|
||||
String currentLine = editor.getText(editor.getCurrentParagraph());
|
||||
|
||||
@ -149,52 +146,26 @@ public class EditorController implements Initializable, Controller, FileManageme
|
||||
*
|
||||
* @param filePath The path of the file
|
||||
*/
|
||||
public void setEditorContent(String filePath) {
|
||||
// if (filePath == null) {
|
||||
// editor.clear();
|
||||
// editor.appendText("// New File");
|
||||
// return;
|
||||
// }
|
||||
try (Scanner sc = new Scanner(new File(filePath))) {
|
||||
// if (filePath.endsWith(".java") || filePath.endsWith(".md")) {
|
||||
editor.clear();
|
||||
while (sc.hasNextLine()) {
|
||||
editor.appendText(sc.nextLine() + "\n");
|
||||
}
|
||||
// } else {
|
||||
// throw new FileNotFoundException();
|
||||
// }
|
||||
|
||||
} catch (FileNotFoundException ex) {
|
||||
Alert error = new Alert(AlertType.ERROR);
|
||||
error.setContentText("Could not be opened!\nMust be a java or md file or not null. Try again.");
|
||||
|
||||
error.showAndWait();
|
||||
System.err.println(filePath);
|
||||
}
|
||||
public void setEditorContent(Path filePath) {
|
||||
String newContent = FileOperations.readFile(filePath);
|
||||
editor.clear();
|
||||
editor.appendText(newContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saving/Writing to the file based on the spesific filepath. Otherwise it will
|
||||
* open an error dialog to give the user feedback about what has happened.
|
||||
*
|
||||
* @param filePath The path of the file
|
||||
*/
|
||||
public void saveCodeArea(String filePath) {
|
||||
try (PrintWriter writer = new PrintWriter(new File(filePath))) {
|
||||
if (filePath.endsWith(".java") || filePath.endsWith(".md")) {
|
||||
writer.println(editor.getText());
|
||||
} else {
|
||||
throw new FileNotFoundException();
|
||||
}
|
||||
public void saveCodeArea(boolean isNewFile) {
|
||||
Stage stage = (Stage) editor.getScene().getWindow();
|
||||
|
||||
} catch (FileNotFoundException ex) {
|
||||
Alert error = new Alert(AlertType.ERROR);
|
||||
error.setContentText("Could not save file!\nMust be a java or md file. Try again.");
|
||||
|
||||
error.showAndWait();
|
||||
System.err.println(filePath);
|
||||
if (isNewFile && FileOperations.saveFileWithDialog(stage, editor.getText())) {
|
||||
this.eventBus.post(new OpenFileEvent(Model.getActiveFilePath()));
|
||||
this.eventBus.post(new FileSaveStateChangedEvent(true));
|
||||
}
|
||||
else if (FileOperations.saveFile(Model.getProjectPath().toString(), editor.getText())) {
|
||||
this.eventBus.post(new FileSaveStateChangedEvent(true));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -219,7 +190,7 @@ public class EditorController implements Initializable, Controller, FileManageme
|
||||
*/
|
||||
@Subscribe
|
||||
private void handle(SaveFileEvent event) {
|
||||
this.saveCodeArea(event.getPath());
|
||||
this.saveCodeArea(event.getIsNewFile());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
|
@ -4,18 +4,12 @@ import javafx.fxml.FXML;
|
||||
import javafx.scene.control.CheckBoxTreeItem;
|
||||
import javafx.scene.control.TreeItem;
|
||||
import javafx.scene.control.TreeView;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.MouseEvent;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
@ -24,6 +18,7 @@ import com.google.common.eventbus.Subscribe;
|
||||
import app.events.FileSelectedEvent;
|
||||
import app.events.OpenProjectEvent;
|
||||
import app.model.Model;
|
||||
import app.service.FiletreeOperations;
|
||||
import javafx.fxml.Initializable;
|
||||
|
||||
/**
|
||||
@ -33,19 +28,11 @@ public class FiletreeController implements Initializable, Controller {
|
||||
|
||||
private EventBus eventBus;
|
||||
|
||||
// Creating the images for the icons.
|
||||
Image folder = new Image(getClass().getResourceAsStream("/graphics/folder.png"));
|
||||
Image md = new Image(getClass().getResourceAsStream("/graphics/md.png"));
|
||||
Image java = new Image(getClass().getResourceAsStream("/graphics/java.png"));
|
||||
Image placeholder = new Image(getClass().getResourceAsStream("/graphics/placeholder.png"));
|
||||
|
||||
@FXML
|
||||
private TreeView<String> filetree;
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||
// TODO: Implement
|
||||
}
|
||||
public void initialize(URL url, ResourceBundle resourceBundle) {}
|
||||
|
||||
@Override
|
||||
public void setEventBus(EventBus eventBus) {
|
||||
@ -67,91 +54,11 @@ public class FiletreeController implements Initializable, Controller {
|
||||
filetree.setShowRoot(false);
|
||||
File fileInputChosen = new File(inputChosen);
|
||||
|
||||
generateTree(fileInputChosen, root);
|
||||
FiletreeOperations.generateTree(fileInputChosen, root);
|
||||
|
||||
filetree.setRoot(root);
|
||||
}
|
||||
|
||||
/**
|
||||
* The method to generate the fileTree recursively. If it is a directory a
|
||||
* CheckBoxStringItem is created and the method is called again. It goes through
|
||||
* all until every directory or file inside the orginal CheckBoxItem is made. If
|
||||
* the item is a file it sends it to the help function checkExtension which is
|
||||
* described below.
|
||||
*/
|
||||
private void generateTree(File file, CheckBoxTreeItem<String> parent) {
|
||||
|
||||
if (file.isDirectory()) {
|
||||
CheckBoxTreeItem<String> element = new CheckBoxTreeItem<>(file.getName(), new ImageView(folder));
|
||||
parent.getChildren().add(element);
|
||||
|
||||
List<File> dirList = new ArrayList<>();
|
||||
List<File> fileList = new ArrayList<>();
|
||||
|
||||
sortFiles(dirList, fileList, file);
|
||||
|
||||
for (File f : dirList) {
|
||||
generateTree(f, element);
|
||||
}
|
||||
|
||||
} else {
|
||||
checkExtensions(file, parent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A helping function to sort the files/folders in the fileTree so that it shows
|
||||
* in the correct order.
|
||||
*/
|
||||
private void sortFiles(List<File> dirList, List<File> fileList, File file) {
|
||||
for (File f : file.listFiles()) {
|
||||
if (f.isDirectory())
|
||||
dirList.add(f);
|
||||
else {
|
||||
fileList.add(f);
|
||||
}
|
||||
|
||||
}
|
||||
dirList.addAll(fileList);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A help function to check if the extensions match .java or .md to insert the
|
||||
* specific icons and sending it to another help funtion createExtension to
|
||||
* create the new CheckboxTreeItem<String> that will add to the parent.
|
||||
*/
|
||||
private void checkExtensions(File file, CheckBoxTreeItem<String> parent) {
|
||||
String name = file.getName();
|
||||
String ext = (name.substring(file.getName().lastIndexOf(".") + 1, file.getName().length()));
|
||||
|
||||
try {
|
||||
createExtension(name, getIconForFile(file), parent);
|
||||
} catch (Exception e) {
|
||||
System.err.println("ICON NOT FOUND: " + file.getPath());
|
||||
}
|
||||
|
||||
// if ("java".equals(ext))
|
||||
// createExtension(name, java, parent);
|
||||
// else if ("md".equals(ext))
|
||||
// createExtension(name, md, parent);
|
||||
// else
|
||||
// createExtension(name, placeholder, parent);
|
||||
}
|
||||
|
||||
private Image getIconForFile(File file) throws IOException {
|
||||
String mimeType = Files.probeContentType(file.toPath()).replace('/', '-');
|
||||
String iconPath = (mimeType != null)
|
||||
? "/graphics/filetreeicons/" + mimeType + ".png"
|
||||
: "/graphics/filetreeicons/file.png";
|
||||
return new Image(getClass().getResourceAsStream(iconPath));
|
||||
}
|
||||
|
||||
private void createExtension(String name, Image image, CheckBoxTreeItem<String> parent) {
|
||||
CheckBoxTreeItem<String> element = new CheckBoxTreeItem<>(name, new ImageView(image));
|
||||
parent.getChildren().add(element);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* MouseClick */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
@ -164,20 +71,14 @@ public class FiletreeController implements Initializable, Controller {
|
||||
private void handleMouseClick(MouseEvent event) {
|
||||
if (event.getClickCount() == 2) {
|
||||
TreeItem<String> item = filetree.getSelectionModel().getSelectedItem();
|
||||
String root = Model.getProjectPath().getFileName().toString();
|
||||
String path = "";
|
||||
while (!root.equals(item.getValue())) {
|
||||
path = File.separator + item.getValue() + path;
|
||||
item = item.getParent();
|
||||
}
|
||||
|
||||
path = Model.getProjectPath() + path;
|
||||
Path pathToString = Paths.get(path);
|
||||
if (!Files.isDirectory(pathToString)) {
|
||||
Model.setActiveFilePath(pathToString);
|
||||
Path path = FiletreeOperations.getPathOfTreeItem(item);
|
||||
|
||||
if (!Files.isDirectory(path)) {
|
||||
// TODO: Add setActiveFilePath Model modification into FileSelectedEvent
|
||||
Model.setActiveFilePath(path);
|
||||
this.eventBus.post(new FileSelectedEvent(path));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,7 +92,7 @@ public class FiletreeController implements Initializable, Controller {
|
||||
|
||||
@Subscribe
|
||||
private void handle(OpenProjectEvent event) {
|
||||
this.showTree(event.getPath());
|
||||
this.showTree(event.getPath().toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,9 +1,8 @@
|
||||
package app.controllers;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
@ -12,7 +11,6 @@ import com.google.common.eventbus.Subscribe;
|
||||
import app.events.CopyEvent;
|
||||
import app.events.CutEvent;
|
||||
import app.events.ExitApplicationEvent;
|
||||
import app.events.FileSaveStateChangedEvent;
|
||||
import app.events.FileSelectedEvent;
|
||||
import app.events.LanguageChangedEvent;
|
||||
import app.events.OpenLinkInBrowserEvent;
|
||||
@ -25,6 +23,8 @@ import app.events.ToggleCommentEvent;
|
||||
import app.events.ToggleWrapTextEvent;
|
||||
import app.events.UndoEvent;
|
||||
import app.model.Model;
|
||||
import app.service.DialogBoxes;
|
||||
import app.service.FileOperations;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
@ -32,8 +32,6 @@ import javafx.scene.control.CheckMenuItem;
|
||||
import javafx.scene.control.MenuBar;
|
||||
import javafx.scene.control.RadioMenuItem;
|
||||
import javafx.scene.control.ToggleGroup;
|
||||
import javafx.stage.DirectoryChooser;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
/**
|
||||
@ -50,9 +48,7 @@ public class MenubarController implements Initializable, Controller {
|
||||
private ToggleGroup languageToggleGroup;
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||
// TODO: implement
|
||||
}
|
||||
public void initialize(URL url, ResourceBundle resourceBundle) {}
|
||||
|
||||
@Override
|
||||
public void setEventBus(EventBus eventBus) {
|
||||
@ -65,6 +61,7 @@ public class MenubarController implements Initializable, Controller {
|
||||
/* ------------------------------------------------------------------------ */
|
||||
@FXML
|
||||
private void handleNewFile() {
|
||||
// TODO: Move Model modification inside event
|
||||
Model.setActiveFilePath(null);
|
||||
this.eventBus.post(new FileSelectedEvent(null));
|
||||
}
|
||||
@ -86,18 +83,17 @@ public class MenubarController implements Initializable, Controller {
|
||||
*/
|
||||
@FXML
|
||||
public void handleOpenFile() {
|
||||
FileChooser fc = new FileChooser();
|
||||
fc.setTitle("Open File");
|
||||
Stage stage = (Stage) menubar.getScene().getWindow();
|
||||
|
||||
File chosenFile = fc.showOpenDialog(stage);
|
||||
if (chosenFile != null) {
|
||||
String correctFormat = chosenFile.getAbsolutePath().replace("\\", "\\\\");
|
||||
try {
|
||||
File file = FileOperations.openFileWithDialog(stage);
|
||||
|
||||
Model.setActiveFilePath(chosenFile.toPath());
|
||||
this.eventBus.post(new FileSelectedEvent(correctFormat));
|
||||
// TODO: Move Model modification inside event
|
||||
Model.setActiveFilePath(file.toPath());
|
||||
this.eventBus.post(new FileSelectedEvent(file.toPath()));
|
||||
} catch (FileNotFoundException e) {
|
||||
DialogBoxes.showErrorMessage("File not found!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -105,19 +101,17 @@ public class MenubarController implements Initializable, Controller {
|
||||
*/
|
||||
@FXML
|
||||
private void handleOpenProject() {
|
||||
DirectoryChooser dc = new DirectoryChooser();
|
||||
dc.setTitle("Open Project");
|
||||
Stage stage = (Stage) menubar.getScene().getWindow();
|
||||
|
||||
File chosenDir = dc.showDialog(stage);
|
||||
if (chosenDir != null) {
|
||||
String correctFormat = chosenDir.getAbsolutePath().replace("\\", "\\\\");
|
||||
|
||||
Model.setProjectPath(chosenDir.toPath());
|
||||
this.eventBus.post(new OpenProjectEvent(correctFormat));
|
||||
try {
|
||||
File dir = FileOperations.openFolderWithDialog(stage);
|
||||
|
||||
// TODO: Move Model modification inside event
|
||||
Model.setProjectPath(dir.toPath());
|
||||
this.eventBus.post(new OpenProjectEvent(dir.toPath()));
|
||||
} catch (FileNotFoundException e) {
|
||||
DialogBoxes.showErrorMessage("Folder not found!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
@ -129,12 +123,10 @@ public class MenubarController implements Initializable, Controller {
|
||||
*/
|
||||
@FXML
|
||||
private void handleSaveFile() {
|
||||
if (Model.getActiveFilePath() != null) {
|
||||
this.eventBus.post(new SaveFileEvent(Model.getActiveFilePath().toString()));
|
||||
this.eventBus.post(new FileSaveStateChangedEvent(true));
|
||||
} else {
|
||||
if (Model.getActiveFilePath() != null)
|
||||
this.eventBus.post(new SaveFileEvent(false));
|
||||
else // New file needs a path
|
||||
handleSaveAsFile();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -142,29 +134,7 @@ public class MenubarController implements Initializable, Controller {
|
||||
*/
|
||||
@FXML
|
||||
private void handleSaveAsFile() {
|
||||
FileChooser fc = new FileChooser();
|
||||
fc.setTitle("Save as");
|
||||
if (Model.getProjectPath() != null) {
|
||||
fc.setInitialDirectory(Model.getProjectPath().toFile());
|
||||
}
|
||||
Stage stage = (Stage) menubar.getScene().getWindow();
|
||||
|
||||
FileChooser.ExtensionFilter extJava = new FileChooser.ExtensionFilter("Java", "*.java");
|
||||
FileChooser.ExtensionFilter extMd = new FileChooser.ExtensionFilter("Markdown", "*.md");
|
||||
|
||||
fc.getExtensionFilters().addAll(extJava, extMd);
|
||||
|
||||
File chosenLocation = fc.showSaveDialog(stage);
|
||||
|
||||
if (chosenLocation != null) {
|
||||
String chosenLocationToString = chosenLocation.toString();
|
||||
this.eventBus.post(new SaveFileEvent(chosenLocationToString));
|
||||
this.eventBus.post(new FileSelectedEvent(chosenLocationToString));
|
||||
|
||||
Path chosenLocationToPath = Paths.get(chosenLocationToString);
|
||||
Model.setActiveFilePath(chosenLocationToPath);
|
||||
this.eventBus.post(new FileSaveStateChangedEvent(true));
|
||||
}
|
||||
this.eventBus.post(new SaveFileEvent(true));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -274,8 +244,15 @@ public class MenubarController implements Initializable, Controller {
|
||||
*/
|
||||
@Subscribe
|
||||
private void handle(LanguageChangedEvent event) {
|
||||
this.languageToggleGroup.getToggles().stream().map(RadioMenuItem.class::cast)
|
||||
.filter(t -> t.getId().equals("toggle" + event.getLanguage())).findFirst().orElseThrow().setSelected(true);
|
||||
this.languageToggleGroup
|
||||
.getToggles()
|
||||
.stream()
|
||||
.map(RadioMenuItem.class::cast)
|
||||
.filter(t -> t.getId()
|
||||
.equals("toggle" + event.getLanguage()))
|
||||
.findFirst()
|
||||
.orElseThrow()
|
||||
.setSelected(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ public class ModelineController implements Initializable, Controller {
|
||||
|
||||
private EventBus eventBus;
|
||||
|
||||
// TODO: Add current filename label
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||
setColumnRow(0, 1);
|
||||
|
@ -1,5 +1,7 @@
|
||||
package app.events;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* Event signalizing that a file was selected in the filetree.
|
||||
*
|
||||
@ -7,7 +9,7 @@ package app.events;
|
||||
*/
|
||||
public class FileSelectedEvent extends Event {
|
||||
|
||||
private String path;
|
||||
private Path path;
|
||||
|
||||
/**
|
||||
* Event signalizing that a file was selected in the filetree.
|
||||
@ -15,14 +17,14 @@ public class FileSelectedEvent extends Event {
|
||||
* Not to be confused with {@link OpenFileEvent}
|
||||
* @param path The path of the selected file
|
||||
*/
|
||||
public FileSelectedEvent(String path) {
|
||||
public FileSelectedEvent(Path path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The path of the selected file
|
||||
*/
|
||||
public String getPath() {
|
||||
public Path getPath() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
package app.events;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* Event signalizing that a file outside the current project is supposed to be opened in the editor.
|
||||
*
|
||||
@ -7,20 +9,20 @@ package app.events;
|
||||
*/
|
||||
public class OpenFileEvent extends Event {
|
||||
|
||||
private String path;
|
||||
private Path path;
|
||||
|
||||
/**
|
||||
* Event signalizing that a file outside the current project is supposed to be opened in the editor.
|
||||
* @param path The path of the file to be opened
|
||||
*/
|
||||
public OpenFileEvent(String path) {
|
||||
public OpenFileEvent(Path path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The path of the file to be opened
|
||||
*/
|
||||
public String getPath() {
|
||||
public Path getPath() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
|
@ -1,24 +1,26 @@
|
||||
package app.events;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* Event signalizing that a folder is supposed to be opened in the filetree.
|
||||
*/
|
||||
public class OpenProjectEvent extends Event {
|
||||
|
||||
private String path;
|
||||
private Path path;
|
||||
|
||||
/**
|
||||
* Event signalizing that a folder is supposed to be opened in the filetree.
|
||||
* @param path The path of the folder to be opened
|
||||
*/
|
||||
public OpenProjectEvent(String path) {
|
||||
public OpenProjectEvent(Path path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The path of the folder to be opened
|
||||
*/
|
||||
public String getPath() {
|
||||
public Path getPath() {
|
||||
return this.path;
|
||||
}
|
||||
}
|
||||
|
@ -2,24 +2,24 @@ package app.events;
|
||||
|
||||
public class SaveFileEvent extends Event {
|
||||
|
||||
private String path;
|
||||
private boolean isNewFile;
|
||||
|
||||
/**
|
||||
* Event signalizing that a file is to be saved.
|
||||
*
|
||||
* Not to be confused with {@link FileSelectedEvent}
|
||||
*
|
||||
* @param path The path of the selected file
|
||||
* @param isNewFile The path of the selected file
|
||||
*/
|
||||
public SaveFileEvent(String path) {
|
||||
this.path = path;
|
||||
public SaveFileEvent(boolean isNewFile) {
|
||||
this.isNewFile = isNewFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The path of the selected file to be saved.
|
||||
* @return Whether or not
|
||||
*/
|
||||
public String getPath() {
|
||||
return this.path;
|
||||
public boolean getIsNewFile() {
|
||||
return this.isNewFile;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,13 +0,0 @@
|
||||
package app.interfaces;
|
||||
|
||||
/*
|
||||
* An interface that contains two methods for reading and writing to files.
|
||||
*/
|
||||
|
||||
public interface FileManagement {
|
||||
|
||||
void setEditorContent(String filePath);
|
||||
|
||||
void saveCodeArea(String filePath);
|
||||
|
||||
}
|
14
src/main/java/app/service/DialogBoxes.java
Normal file
14
src/main/java/app/service/DialogBoxes.java
Normal file
@ -0,0 +1,14 @@
|
||||
package app.service;
|
||||
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Alert.AlertType;
|
||||
|
||||
public class DialogBoxes {
|
||||
|
||||
public static void showErrorMessage(String errorMessage) {
|
||||
Alert error = new Alert(AlertType.ERROR);
|
||||
error.setContentText(errorMessage);
|
||||
error.showAndWait();
|
||||
}
|
||||
|
||||
}
|
118
src/main/java/app/service/FileOperations.java
Normal file
118
src/main/java/app/service/FileOperations.java
Normal file
@ -0,0 +1,118 @@
|
||||
package app.service;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Scanner;
|
||||
|
||||
import app.model.Model;
|
||||
import javafx.stage.DirectoryChooser;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
public class FileOperations {
|
||||
|
||||
// FIXME: This class contains bugs when opening fiies and folders.
|
||||
// TODO: Needs documentation and cleanup
|
||||
// TODO: This class needs to be extensively error checked
|
||||
|
||||
public static File openFileWithDialog(Stage stage) throws FileNotFoundException {
|
||||
|
||||
FileChooser fc = new FileChooser();
|
||||
fc.setTitle("Open File");
|
||||
|
||||
File chosenFile = fc.showOpenDialog(stage);
|
||||
|
||||
if (chosenFile == null)
|
||||
throw new FileNotFoundException();
|
||||
// if (chosenFile != null) {
|
||||
// String correctFormat = chosenFile.getAbsolutePath().replace("\\", "\\\\");
|
||||
// }
|
||||
|
||||
return chosenFile;
|
||||
|
||||
}
|
||||
|
||||
public static File openFolderWithDialog(Stage stage) throws FileNotFoundException {
|
||||
|
||||
DirectoryChooser dc = new DirectoryChooser();
|
||||
dc.setTitle("Open Project");
|
||||
|
||||
File dir = dc.showDialog(stage);
|
||||
|
||||
if (dir == null)
|
||||
throw new FileNotFoundException();
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
public static boolean saveFile(String filepath, String content) {
|
||||
|
||||
try (PrintWriter writer = new PrintWriter(new File(filepath))) {
|
||||
if (filepath.endsWith(".java") || filepath.endsWith(".md")) {
|
||||
writer.println(content);
|
||||
} else {
|
||||
throw new FileNotFoundException();
|
||||
}
|
||||
|
||||
} catch (FileNotFoundException ex) {
|
||||
|
||||
DialogBoxes.showErrorMessage("Could not save file!\nMust be a java or md file. Try again.");
|
||||
System.err.println(filepath);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public static boolean saveFileWithDialog(Stage stage, String content) {
|
||||
FileChooser fc = new FileChooser();
|
||||
fc.setTitle("Save as");
|
||||
|
||||
if (Model.getProjectPath() != null)
|
||||
fc.setInitialDirectory(Model.getProjectPath().toFile());
|
||||
|
||||
FileChooser.ExtensionFilter extJava = new FileChooser.ExtensionFilter("Java", "*.java");
|
||||
FileChooser.ExtensionFilter extMd = new FileChooser.ExtensionFilter("Markdown", "*.md");
|
||||
|
||||
fc.getExtensionFilters().addAll(extJava, extMd);
|
||||
|
||||
File chosenLocation = fc.showSaveDialog(stage);
|
||||
if (chosenLocation == null)
|
||||
return false;
|
||||
|
||||
if (saveFile(chosenLocation.getAbsolutePath(), content)) {
|
||||
Model.setActiveFilePath(chosenLocation.toPath());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String readFile(Path filePath) {
|
||||
|
||||
if (filePath == null)
|
||||
return "";
|
||||
|
||||
String result = "";
|
||||
|
||||
try (Scanner sc = new Scanner(filePath.toFile())) {
|
||||
if (filePath.endsWith(".java") || filePath.endsWith(".md")) {
|
||||
while (sc.hasNextLine()) {
|
||||
result += (sc.nextLine() + "\n");
|
||||
}
|
||||
} else {
|
||||
throw new FileNotFoundException();
|
||||
}
|
||||
|
||||
} catch (FileNotFoundException ex) {
|
||||
DialogBoxes.showErrorMessage("Could not be opened!\nMust be a java or md file or not null. Try again.");
|
||||
System.err.println(filePath);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
}
|
146
src/main/java/app/service/FiletreeOperations.java
Normal file
146
src/main/java/app/service/FiletreeOperations.java
Normal file
@ -0,0 +1,146 @@
|
||||
package app.service;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import app.model.Model;
|
||||
import javafx.scene.control.CheckBoxTreeItem;
|
||||
import javafx.scene.control.TreeItem;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
|
||||
public class FiletreeOperations {
|
||||
|
||||
// FIXME: File specific icons not working properly
|
||||
// TODO: Clean up code that is not in use
|
||||
|
||||
// Creating the images for the icons.
|
||||
Image folder = new Image(getClass().getResourceAsStream("/graphics/folder.png"));
|
||||
Image md = new Image(getClass().getResourceAsStream("/graphics/md.png"));
|
||||
Image java = new Image(getClass().getResourceAsStream("/graphics/java.png"));
|
||||
Image placeholder = new Image(getClass().getResourceAsStream("/graphics/placeholder.png"));
|
||||
|
||||
// TODO: Error check for recursiveness, and files without icons
|
||||
|
||||
/**
|
||||
* The method to generate the fileTree recursively. If it is a directory a
|
||||
* CheckBoxStringItem is created and the method is called again. It goes through
|
||||
* all until every directory or file inside the orginal CheckBoxItem is made. If
|
||||
* the item is a file it sends it to the help function checkExtension which is
|
||||
* described below.
|
||||
*/
|
||||
public static void generateTree(File file, CheckBoxTreeItem<String> parent) {
|
||||
|
||||
Image folder = new Image(FiletreeOperations.class.getResourceAsStream("/graphics/folder.png"));
|
||||
|
||||
if (file.isDirectory()) {
|
||||
CheckBoxTreeItem<String> element = new CheckBoxTreeItem<>(file.getName(), new ImageView(folder));
|
||||
parent.getChildren().add(element);
|
||||
|
||||
List<File> dirList = new ArrayList<>();
|
||||
List<File> fileList = new ArrayList<>();
|
||||
|
||||
sortFiles(dirList, fileList, file);
|
||||
|
||||
for (File f : dirList) {
|
||||
generateTree(f, element);
|
||||
}
|
||||
|
||||
} else {
|
||||
checkExtensions(file, parent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A helping function to sort the files/folders in the fileTree so that it shows
|
||||
* in the correct order.
|
||||
*/
|
||||
private static void sortFiles(List<File> dirList, List<File> fileList, File file) {
|
||||
for (File f : file.listFiles()) {
|
||||
if (f.isDirectory())
|
||||
dirList.add(f);
|
||||
else
|
||||
fileList.add(f);
|
||||
}
|
||||
dirList.addAll(fileList);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A help function to check if the extensions match .java or .md to insert the
|
||||
* specific icons and sending it to another help funtion createExtension to
|
||||
* create the new CheckboxTreeItem<String> that will add to the parent.
|
||||
*/
|
||||
private static void checkExtensions(File file, CheckBoxTreeItem<String> parent) {
|
||||
String name = file.getName();
|
||||
String ext = (name.substring(file.getName().lastIndexOf(".") + 1, file.getName().length()));
|
||||
|
||||
try {
|
||||
createExtension(name, getIconForFile(file), parent);
|
||||
} catch (Exception e) {
|
||||
System.err.println("[ERROR]: DEFAULT FILE ICON NOT FOUND");
|
||||
}
|
||||
|
||||
// if ("java".equals(ext))
|
||||
// createExtension(name, java, parent);
|
||||
// else if ("md".equals(ext))
|
||||
// createExtension(name, md, parent);
|
||||
// else
|
||||
// createExtension(name, placeholder, parent);
|
||||
}
|
||||
|
||||
private static Image getIconForFile(File file) throws IOException {
|
||||
Image icon;
|
||||
|
||||
try {
|
||||
String mimeType = Files.probeContentType(file.toPath()).replace('/', '-');
|
||||
|
||||
String iconPath = "/graphics/filetreeicons/" + mimeType + ".png";
|
||||
if (mimeType == null) throw new IOException();
|
||||
|
||||
InputStream imageData = FiletreeOperations.class.getResourceAsStream(iconPath);
|
||||
if (imageData == null) throw new IOException();
|
||||
|
||||
icon = new Image(imageData);
|
||||
|
||||
} catch (IOException e) {
|
||||
System.err.println("[ERROR]: ICON NOT FOUND: " + file.getPath());
|
||||
|
||||
// String iconPath = "/graphics/filetreeicons/file.png";
|
||||
String iconPath = "/graphics/placeholder.png";
|
||||
|
||||
InputStream imageData = FileOperations.class.getResourceAsStream(iconPath);
|
||||
if (imageData == null) throw new IOException();
|
||||
|
||||
icon = new Image(imageData);
|
||||
}
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
private static void createExtension(String name, Image image, CheckBoxTreeItem<String> parent) {
|
||||
CheckBoxTreeItem<String> element = new CheckBoxTreeItem<>(name, new ImageView(image));
|
||||
parent.getChildren().add(element);
|
||||
}
|
||||
|
||||
public static Path getPathOfTreeItem(TreeItem<String> item) {
|
||||
String root = Model.getProjectPath().getFileName().toString();
|
||||
String path = "";
|
||||
while (!root.equals(item.getValue())) {
|
||||
path = File.separator + item.getValue() + path;
|
||||
item = item.getParent();
|
||||
}
|
||||
|
||||
path = Model.getProjectPath().toString() + path;
|
||||
Path pathToString = Paths.get(path);
|
||||
|
||||
return pathToString;
|
||||
}
|
||||
|
||||
}
|
@ -37,6 +37,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import app.testing.FxTestTemplate;
|
||||
import app.model.Model;
|
||||
import app.model.ProgrammingLanguage;
|
||||
import app.service.FileOperations;
|
||||
import app.service.LanguageOperations;
|
||||
import app.events.CopyEvent;
|
||||
import app.events.CutEvent;
|
||||
@ -88,16 +89,14 @@ public class EditorControllerTest extends FxTestTemplate {
|
||||
String resourcePath = "/testfile.txt";
|
||||
String filePath = getClass().getResource(resourcePath).getPath();
|
||||
File file = new File(filePath);
|
||||
List<String> content =
|
||||
Files.readAllLines(file.toPath())
|
||||
.stream()
|
||||
.map(s -> s + "\n")
|
||||
.collect(Collectors.toList());
|
||||
|
||||
eventBus.post(new FileSelectedEvent(filePath));
|
||||
verify(editor, times(content.size())).appendText(captor.capture());
|
||||
eventBus.post(new FileSelectedEvent(file.toPath()));
|
||||
try (MockedStatic<FileOperations> mocked = mockStatic(FileOperations.class)) {
|
||||
mocked.when(() -> FileOperations.readFile(any()))
|
||||
.thenReturn("");
|
||||
|
||||
assertEquals(content, captor.getAllValues());
|
||||
mocked.verify(() -> FileOperations.readFile(file.toPath()));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -105,7 +104,7 @@ public class EditorControllerTest extends FxTestTemplate {
|
||||
public void testFileSelectedEventWithUnrealFile() throws IOException {
|
||||
|
||||
String brokenFilePath = "/doesNotExist.txt";
|
||||
eventBus.post(new FileSelectedEvent(brokenFilePath));
|
||||
eventBus.post(new FileSelectedEvent(new File(brokenFilePath).toPath()));
|
||||
|
||||
verify(editor, never()).clear();
|
||||
}
|
||||
|
46
src/test/java/app/controllers/MenubarControllerTest.java
Normal file
46
src/test/java/app/controllers/MenubarControllerTest.java
Normal file
@ -0,0 +1,46 @@
|
||||
package app.controllers;
|
||||
|
||||
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.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import app.testing.FxTestTemplate;
|
||||
import javafx.scene.control.MenuBar;
|
||||
import javafx.scene.control.ToggleGroup;
|
||||
|
||||
// https://stackoverflow.com/questions/60403458/testing-overriden-eventhandler-in-java-javafx-spring-boot
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class MenubarControllerTest extends FxTestTemplate {
|
||||
|
||||
@Mock
|
||||
private MenuBar menubar;
|
||||
|
||||
@Mock
|
||||
private ToggleGroup languageToggleGroup;
|
||||
|
||||
private EventBus eventBus;
|
||||
|
||||
@InjectMocks
|
||||
private MenubarController controller;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void insertEventBus() {
|
||||
this.eventBus = new EventBus();
|
||||
this.controller.setEventBus(eventBus);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("")
|
||||
public void testHandleOpenFile() {
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user