Add several pieces of documentation
This commit is contained in:
parent
09118ee3b2
commit
41362a45d4
5
pom.xml
5
pom.xml
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>tdt4100-v2021</groupId>
|
<groupId>tdt4100-v2021</groupId>
|
||||||
<artifactId>project</artifactId>
|
<artifactId>banana-editor</artifactId>
|
||||||
<version>1.0.0</version>
|
<version>1.0.0</version>
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
@ -99,9 +99,6 @@
|
||||||
<argLine>@{argLine} --enable-preview</argLine>
|
<argLine>@{argLine} --enable-preview</argLine>
|
||||||
<forkCount>1</forkCount>
|
<forkCount>1</forkCount>
|
||||||
<reuseForks>true</reuseForks>
|
<reuseForks>true</reuseForks>
|
||||||
<!-- <includes>
|
|
||||||
<include>**/test/**/*Test.java</include>
|
|
||||||
</includes> -->
|
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
|
|
|
@ -37,11 +37,19 @@ public class Main extends Application {
|
||||||
window.getIcons().add(new Image(getClass().getResourceAsStream(ICON_PATH)));
|
window.getIcons().add(new Image(getClass().getResourceAsStream(ICON_PATH)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads all FXML documents of the main UI and initializes all correlated subcontrollers
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
private void loadFXML() throws IOException {
|
private void loadFXML() throws IOException {
|
||||||
|
// TODO: Error handle this function.
|
||||||
this.fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/Main.fxml"));
|
this.fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/Main.fxml"));
|
||||||
this.fxmlRoot = fxmlLoader.load();
|
this.fxmlRoot = fxmlLoader.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a scene for the window, and adds it to {@link Model}
|
||||||
|
*/
|
||||||
private void createScene() {
|
private void createScene() {
|
||||||
this.scene = new Scene(fxmlRoot);
|
this.scene = new Scene(fxmlRoot);
|
||||||
Model.setScene(scene);
|
Model.setScene(scene);
|
||||||
|
|
|
@ -46,31 +46,47 @@ public class MainController implements Initializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the global eventbus.
|
* Get the global eventbus
|
||||||
*
|
*
|
||||||
* @return The eventbus
|
* @return The EventBus object
|
||||||
*/
|
*/
|
||||||
public EventBus getEventBus() {
|
public EventBus getEventBus() {
|
||||||
return this.eventBus;
|
return this.eventBus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the global Host Services API
|
||||||
|
*
|
||||||
|
* @return The JavaFX HostServices object
|
||||||
|
* @see #setHostServices(HostServices)
|
||||||
|
*/
|
||||||
public HostServices getHostServices() {
|
public HostServices getHostServices() {
|
||||||
return hostServices;
|
return hostServices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a reference to the global Host Services API
|
||||||
|
* @param hostServices The JavaFX HostServices object
|
||||||
|
* @see #getHostServices()
|
||||||
|
*/
|
||||||
public void setHostServices(HostServices hostServices) {
|
public void setHostServices(HostServices hostServices) {
|
||||||
this.hostServices = hostServices;
|
this.hostServices = hostServices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace a CSS file in a specific location in the application CSS array
|
||||||
|
* @param position The position of the CSS file to replace
|
||||||
|
* @param cssPath The path in resources to the new CSS file
|
||||||
|
*/
|
||||||
private void setCSSAt(int position, String cssPath) {
|
private void setCSSAt(int position, String cssPath) {
|
||||||
|
//TODO: Error check that position in range 0 to 1
|
||||||
String nextStyleSheet = getClass().getResource(cssPath).toExternalForm();
|
String nextStyleSheet = getClass().getResource(cssPath).toExternalForm();
|
||||||
|
|
||||||
Model.getScene().getStylesheets().set(position, nextStyleSheet);
|
Model.getScene().getStylesheets().set(position, nextStyleSheet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
|
@ -78,19 +94,26 @@ public class MainController implements Initializable {
|
||||||
this.setCSSAt(1, "/styling/languages/" + event.getLanguage().toLowerCase() + ".css");
|
this.setCSSAt(1, "/styling/languages/" + event.getLanguage().toLowerCase() + ".css");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the CSS according to which theme the user chooses
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void handle(ThemeChangedEvent event) {
|
private void handle(ThemeChangedEvent event) {
|
||||||
this.setCSSAt(0, "/styling/themes/" + event.getTheme().toLowerCase().replace(" ", "-") + ".css");
|
this.setCSSAt(0, "/styling/themes/" + event.getTheme().toLowerCase().replace(" ", "-") + ".css");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a link in the browser.
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void handle(OpenLinkInBrowserEvent event) {
|
private void handle(OpenLinkInBrowserEvent event) {
|
||||||
this.getHostServices().showDocument(event.getLink());
|
this.getHostServices().showDocument(event.getLink());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle an exit request for the whole program.
|
* Handle an exit request for the whole program
|
||||||
*
|
|
||||||
* @param event
|
* @param event
|
||||||
*/
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
|
|
|
@ -53,7 +53,7 @@ public class ModelineController implements Initializable, Controller {
|
||||||
*/
|
*/
|
||||||
@Subscribe
|
@Subscribe
|
||||||
private void handle(EditorChangedEvent event) {
|
private void handle(EditorChangedEvent event) {
|
||||||
this.setColumnRow(event.getColumn(), event.getLineNumber());
|
this.setColumnRow(event.getColumn(), event.getLine());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package app.events;
|
package app.events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event signalizing that something is being copied to the clipboard in an arbitrary place in the UI
|
||||||
|
*/
|
||||||
public class CopyEvent extends Event {
|
public class CopyEvent extends Event {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package app.events;
|
package app.events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event signalizing that something is being cut to the clipboard in an arbitrary place in the UI
|
||||||
|
*/
|
||||||
public class CutEvent extends Event {
|
public class CutEvent extends Event {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,33 @@
|
||||||
package app.events;
|
package app.events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event signalizing that the content or the cursor state in the editor has been modified
|
||||||
|
*/
|
||||||
public class EditorChangedEvent extends Event {
|
public class EditorChangedEvent extends Event {
|
||||||
|
|
||||||
private int lineNumber;
|
private int line;
|
||||||
private int column;
|
private int column;
|
||||||
|
|
||||||
public EditorChangedEvent(int lineNumber, int column) {
|
/**
|
||||||
this.lineNumber = lineNumber;
|
* Event signalizing that the content or the cursor state in the editor has been modified
|
||||||
|
* @param line The line number of the cursor
|
||||||
|
* @param column The column number of the cursor
|
||||||
|
*/
|
||||||
|
public EditorChangedEvent(int line, int column) {
|
||||||
|
this.line = line;
|
||||||
this.column = column;
|
this.column = column;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLineNumber() {
|
/**
|
||||||
return this.lineNumber;
|
* @return The line number of the cursor
|
||||||
|
*/
|
||||||
|
public int getLine() {
|
||||||
|
return this.line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The column number of the cursor
|
||||||
|
*/
|
||||||
public int getColumn() {
|
public int getColumn() {
|
||||||
return column;
|
return column;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
package app.events;
|
package app.events;
|
||||||
|
|
||||||
class Event {}
|
/**
|
||||||
|
* Base class for any type of event of the eventbus
|
||||||
|
*/
|
||||||
|
abstract class Event {}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package app.events;
|
package app.events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event signalizing a shutdown request for the whole applicaton
|
||||||
|
*/
|
||||||
public class ExitApplicationEvent extends Event {
|
public class ExitApplicationEvent extends Event {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,15 +2,25 @@ package app.events;
|
||||||
|
|
||||||
import app.model.Model;
|
import app.model.Model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event signalizing that the current file either has been modified or saved
|
||||||
|
*/
|
||||||
public class FileSaveStateChangedEvent extends Event {
|
public class FileSaveStateChangedEvent extends Event {
|
||||||
|
|
||||||
private boolean isSaved;
|
private boolean isSaved;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event signalizing that the current file either has been modified or saved
|
||||||
|
* @param isSaved Whether or not the file has been modified or saved
|
||||||
|
*/
|
||||||
public FileSaveStateChangedEvent(boolean isSaved) {
|
public FileSaveStateChangedEvent(boolean isSaved) {
|
||||||
this.isSaved = isSaved;
|
this.isSaved = isSaved;
|
||||||
Model.setFileIsSaved(isSaved);
|
Model.setFileIsSaved(isSaved);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Whether or not the file has been modified or saved
|
||||||
|
*/
|
||||||
public boolean getIsSaved() {
|
public boolean getIsSaved() {
|
||||||
return this.isSaved;
|
return this.isSaved;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,27 @@
|
||||||
package app.events;
|
package app.events;
|
||||||
|
|
||||||
public class FileSelectedEvent {
|
/**
|
||||||
|
* Event signalizing that a file was selected in the filetree.
|
||||||
|
*
|
||||||
|
* Not to be confused with {@link OpenFileEvent}
|
||||||
|
*/
|
||||||
|
public class FileSelectedEvent extends Event {
|
||||||
|
|
||||||
private String path;
|
private String path;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event signalizing that a file was selected in the filetree.
|
||||||
|
*
|
||||||
|
* Not to be confused with {@link OpenFileEvent}
|
||||||
|
* @param path The path of the selected file
|
||||||
|
*/
|
||||||
public FileSelectedEvent(String path) {
|
public FileSelectedEvent(String path) {
|
||||||
this.path = path;
|
this.path = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The path of the selected file
|
||||||
|
*/
|
||||||
public String getPath() {
|
public String getPath() {
|
||||||
return this.path;
|
return this.path;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
package app.events;
|
package app.events;
|
||||||
|
|
||||||
import app.model.languages.Java;
|
import app.model.languages.*;
|
||||||
import app.model.languages.Markdown;
|
|
||||||
import app.model.Model;
|
import app.model.Model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event signalizing that the programming language of the editor has changed
|
||||||
|
*/
|
||||||
public class LanguageChangedEvent extends Event {
|
public class LanguageChangedEvent extends Event {
|
||||||
|
|
||||||
private String language;
|
private String language;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event signalizing that the programming language of the editor has changed
|
||||||
|
* @param language The name of the language, capitalized
|
||||||
|
*/
|
||||||
public LanguageChangedEvent(String language) {
|
public LanguageChangedEvent(String language) {
|
||||||
this.language = language;
|
this.language = language;
|
||||||
|
|
||||||
|
@ -26,6 +32,9 @@ public class LanguageChangedEvent extends Event {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The name of the language
|
||||||
|
*/
|
||||||
public String getLanguage() {
|
public String getLanguage() {
|
||||||
return language;
|
return language;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,25 @@
|
||||||
package app.events;
|
package app.events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event signalizing that a file outside the current project is supposed to be opened in the editor.
|
||||||
|
*
|
||||||
|
* Not to be confused with {@link FileSelectedEvent}
|
||||||
|
*/
|
||||||
public class OpenFileEvent extends Event {
|
public class OpenFileEvent extends Event {
|
||||||
|
|
||||||
private String path;
|
private String 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(String path) {
|
||||||
this.path = path;
|
this.path = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The path of the file to be opened
|
||||||
|
*/
|
||||||
public String getPath() {
|
public String getPath() {
|
||||||
return this.path;
|
return this.path;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,23 @@
|
||||||
package app.events;
|
package app.events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event signalizing that the application is going to open a link in an external browser
|
||||||
|
*/
|
||||||
public class OpenLinkInBrowserEvent extends Event {
|
public class OpenLinkInBrowserEvent extends Event {
|
||||||
|
|
||||||
private String link;
|
private String link;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event signalizing that the application is going to open a link in an external browser
|
||||||
|
* @param link The link to open
|
||||||
|
*/
|
||||||
public OpenLinkInBrowserEvent(String link) {
|
public OpenLinkInBrowserEvent(String link) {
|
||||||
this.link = link;
|
this.link = link;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The link to open
|
||||||
|
*/
|
||||||
public String getLink() {
|
public String getLink() {
|
||||||
return link;
|
return link;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,23 @@
|
||||||
package app.events;
|
package app.events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event signalizing that a folder is supposed to be opened in the filetree.
|
||||||
|
*/
|
||||||
public class OpenProjectEvent extends Event {
|
public class OpenProjectEvent extends Event {
|
||||||
|
|
||||||
private String path;
|
private String 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(String path) {
|
||||||
this.path = path;
|
this.path = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The path of the folder to be opened
|
||||||
|
*/
|
||||||
public String getPath() {
|
public String getPath() {
|
||||||
return this.path;
|
return this.path;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package app.events;
|
package app.events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event signalizing that something is being pasted from the clipboard in an arbitrary place in the UI
|
||||||
|
*/
|
||||||
public class PasteEvent extends Event {
|
public class PasteEvent extends Event {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package app.events;
|
package app.events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event signalizing that an action is being undone in an arbitrary place in the UI
|
||||||
|
*/
|
||||||
public class RedoEvent extends Event {
|
public class RedoEvent extends Event {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,23 @@
|
||||||
package app.events;
|
package app.events;
|
||||||
|
|
||||||
public class ThemeChangedEvent {
|
/**
|
||||||
|
* Event signalizing that the theme of the applicaton has been changed
|
||||||
|
*/
|
||||||
|
public class ThemeChangedEvent extends Event {
|
||||||
|
|
||||||
private String theme;
|
private String theme;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event signalizing that the theme of the applicaton has been changed
|
||||||
|
* @param theme The name of the theme
|
||||||
|
*/
|
||||||
public ThemeChangedEvent(String theme) {
|
public ThemeChangedEvent(String theme) {
|
||||||
this.theme = theme;
|
this.theme = theme;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The name of the theme
|
||||||
|
*/
|
||||||
public String getTheme() {
|
public String getTheme() {
|
||||||
return theme;
|
return theme;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package app.events;
|
package app.events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event signalizing that the editor is going to toggle a language specific comment of a line or selecton
|
||||||
|
*/
|
||||||
public class ToggleCommentEvent extends Event {
|
public class ToggleCommentEvent extends Event {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,23 @@
|
||||||
package app.events;
|
package app.events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event signalizing that the editor wrap text function was toggled on or off
|
||||||
|
*/
|
||||||
public class ToggleWrapTextEvent extends Event {
|
public class ToggleWrapTextEvent extends Event {
|
||||||
|
|
||||||
private boolean isWrapped;
|
private boolean isWrapped;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event signalizing that the editor wraptext function was toggled on or off
|
||||||
|
* @param isWrapped Whether or not wraptext was turned on or off
|
||||||
|
*/
|
||||||
public ToggleWrapTextEvent(boolean isWrapped) {
|
public ToggleWrapTextEvent(boolean isWrapped) {
|
||||||
this.isWrapped = isWrapped;
|
this.isWrapped = isWrapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Whether or not wraptext was turned on or off
|
||||||
|
*/
|
||||||
public boolean getIsWrapped() {
|
public boolean getIsWrapped() {
|
||||||
return this.isWrapped;
|
return this.isWrapped;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package app.events;
|
package app.events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event signalizing that an action is being undone in an arbitrary place in the UI
|
||||||
|
*/
|
||||||
public class UndoEvent extends Event {
|
public class UndoEvent extends Event {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import javafx.scene.Scene;
|
||||||
* Data model of the application.
|
* Data model of the application.
|
||||||
*
|
*
|
||||||
* Contains a static reference to state that has to be accessed by multiple
|
* Contains a static reference to state that has to be accessed by multiple
|
||||||
* pieces in the application, including the primary scene.
|
* pieces in the application, including the state like primary scene.
|
||||||
*/
|
*/
|
||||||
public class Model {
|
public class Model {
|
||||||
private static boolean fileIsSaved;
|
private static boolean fileIsSaved;
|
||||||
|
|
|
@ -11,14 +11,28 @@ import app.model.ProgrammingLanguage;
|
||||||
|
|
||||||
public class LanguageOperations {
|
public class LanguageOperations {
|
||||||
|
|
||||||
private static String getMatch(Matcher m, Collection<String> kws) {
|
/**
|
||||||
return kws
|
* Use a matcher to find the styleclass of the next match
|
||||||
|
* from several available styleclasses.
|
||||||
|
* @param m The matcher
|
||||||
|
* @param styleClasses Collection of styleclasses
|
||||||
|
* @return The styleclass of the next match
|
||||||
|
*/
|
||||||
|
private static String getMatch(Matcher m, Collection<String> styleClasses) {
|
||||||
|
return styleClasses
|
||||||
.stream()
|
.stream()
|
||||||
.filter(keyword -> m.group(keyword) != null)
|
.filter(keyword -> m.group(keyword) != null)
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElse(""); // This is not possible, but is needed to convert Optional<String> to String
|
.orElse(""); // This is not possible, but is needed to convert Optional<String> to String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate syntax highlighting data for a code area
|
||||||
|
* @param text The text to highlight
|
||||||
|
* @param language The language object to use for highlighting
|
||||||
|
* @return The syntax highlighting data
|
||||||
|
* @see app.controllers.EditorController#setHighlighting(StyleSpans) EditorController.setHighlighting()
|
||||||
|
*/
|
||||||
public static StyleSpans<Collection<String>>
|
public static StyleSpans<Collection<String>>
|
||||||
syntaxHighlight(String text, ProgrammingLanguage language) {
|
syntaxHighlight(String text, ProgrammingLanguage language) {
|
||||||
Matcher matcher = language.getPattern().matcher(text);
|
Matcher matcher = language.getPattern().matcher(text);
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
package service;
|
|
||||||
|
|
||||||
public class FileOperations {
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue