diff --git a/.idea/.gitignore b/.idea/.gitignore index 26d33521af10bcc7fd8cea344038eaaeb78d0ef5..050d7250b2a99f36d17c313ffe81bf32471756eb 100644 --- a/.idea/.gitignore +++ b/.idea/.gitignore @@ -1,3 +1,4 @@ # Default ignored files /shelf/ /workspace.xml +codeStyles/ \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000000000000000000000000000000000000..2b63946d5b31084bbb7dda418ceb3d75eb686373 --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="Palette2"> + <group name="Swing"> + <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" /> + </item> + <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" /> + </item> + <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" /> + </item> + <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true"> + <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" /> + </item> + <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" /> + <initial-values> + <property name="text" value="Button" /> + </initial-values> + </item> + <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" /> + <initial-values> + <property name="text" value="RadioButton" /> + </initial-values> + </item> + <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" /> + <initial-values> + <property name="text" value="CheckBox" /> + </initial-values> + </item> + <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" /> + <initial-values> + <property name="text" value="Label" /> + </initial-values> + </item> + <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> + <preferred-size width="150" height="-1" /> + </default-constraints> + </item> + <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> + <preferred-size width="150" height="-1" /> + </default-constraints> + </item> + <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> + <preferred-size width="150" height="-1" /> + </default-constraints> + </item> + <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> + <preferred-size width="150" height="50" /> + </default-constraints> + </item> + <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> + <preferred-size width="150" height="50" /> + </default-constraints> + </item> + <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> + <preferred-size width="150" height="50" /> + </default-constraints> + </item> + <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" /> + </item> + <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> + <preferred-size width="150" height="50" /> + </default-constraints> + </item> + <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3"> + <preferred-size width="150" height="50" /> + </default-constraints> + </item> + <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> + <preferred-size width="150" height="50" /> + </default-constraints> + </item> + <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3"> + <preferred-size width="200" height="200" /> + </default-constraints> + </item> + <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3"> + <preferred-size width="200" height="200" /> + </default-constraints> + </item> + <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" /> + </item> + <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" /> + </item> + <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" /> + </item> + <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" /> + </item> + <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1"> + <preferred-size width="-1" height="20" /> + </default-constraints> + </item> + <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false"> + <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" /> + </item> + <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false"> + <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" /> + </item> + </group> + </component> +</project> \ No newline at end of file diff --git a/console/src/main/kotlin/notes/multi/console/Console.kt b/console/src/main/kotlin/notes/multi/console/Console.kt index 3412f38d62515dfa351ba2e55ae90c1ec70a4ab0..2f4cde52892c626fa7565932845e042e07f3b1e8 100644 --- a/console/src/main/kotlin/notes/multi/console/Console.kt +++ b/console/src/main/kotlin/notes/multi/console/Console.kt @@ -3,22 +3,79 @@ */ package notes.multi.console -import notes.multi.utilities.Filemanager +import java.lang.IllegalArgumentException -import notes.multi.utilities.Note import notes.multi.utilities.TextWindow import javafx.application.Application -import javafx.stage.Stage - -fun main() { - // thesea re test functions feel free to use - val n = Note() - val noteTitle = "testver2.txt" - val path = "${System.getProperty("user.dir")}/test/" - Application.launch(TextWindow()::class.java, "--title=${noteTitle}", "--text=${path}") - - // val f = Filemanager("${System.getProperty("user.dir")}/test/", "hello.txt") - // f.writefile("hello world") - // f.deletefile() - // println(f.openfile()) +import kotlin.io.path.Path +import java.io.File + + +fun main(args: Array<String>) { + try { + if (args.isEmpty()) { + println( + """ + +-------------------------------------------------------------------------------------+ + WELCOME TO TEAM 112'S CONSOLE BASED NOTES APP + + This application is a working console-based prototype for the + note taking application that the team will be delivering at the end of the term. + + With this simple app, users can: + 1. Create Notes + 2. Edit Notes + 3. Delete Notes + 4. Close GUI Window + + 1. Create Notes + - To create notes, users must type "./console <filename>" + - To save changes, use the Ctrl + S keybinding + + 2. Edit Notes + - To edit notes, users must type "./console <filename>" + - If the file doesn't exist, a new note will be created + - To save changes, use the Ctrl + S keybinding + + 3. Delete Notes + - To delete a note, use the Ctrl + D keybinding + + 4. Close GUI Window + - To close the GUI window, use the Ctrl + W keybinding + + +-------------------------------------------------------------------------------------+ + """.trimIndent() + ) + } else { + if (args.size < 2) { + + /** + * File Path (can be relative or absolute) + */ + val filePathArg = args[0] + + /** + * Title of the file + */ + val fileTitle = Path(filePathArg).fileName + + /** + * Location of the file as text + */ + val fileLocation = Path(filePathArg).parent ?: System.getProperty("user.dir") + if (!File(fileLocation.toString()).isDirectory) throw IllegalArgumentException("[ERROR]: Directory does not exist!") + + // Regex Check for a specific argument format: + ConsoleUtils.verifyFilename(fileTitle.toString(), Regex("^.*[.]([Mm][Dd]|[Tt][Xx][Tt])$")) + + // Passing the location and title as params to TextWindow + Application.launch(TextWindow()::class.java, "--title=$fileTitle", "--text=$fileLocation") + } else { + throw IllegalArgumentException("[ERROR]: Wrong number of arguments provided!") + } + } + } catch (err: IllegalArgumentException) { + System.err.println(err.message) + } } + diff --git a/console/src/main/kotlin/notes/multi/console/ConsoleUtils.kt b/console/src/main/kotlin/notes/multi/console/ConsoleUtils.kt new file mode 100644 index 0000000000000000000000000000000000000000..8c800f1aaa35b71fa554fc41bfd05b0fce352541 --- /dev/null +++ b/console/src/main/kotlin/notes/multi/console/ConsoleUtils.kt @@ -0,0 +1,22 @@ +/* + * This Kotlin source file was generated by the Gradle 'init' task. + */ +package notes.multi.console +import java.lang.IllegalArgumentException + +class ConsoleUtils { + companion object { + /** + * Checks the `filename` inputted and throws an exception + * if the `filename` does not follow the regular expression `pattern` + * @param filename Name of the file + * @param pattern Regular expression pattern + * @throws IllegalArgumentException + */ + fun verifyFilename(filename: String, pattern: Regex) { + if (!(pattern matches filename)) { + throw IllegalArgumentException("[ERROR]: File name does not follow the required input pattern") + } + } + } +} diff --git a/console/src/main/kotlin/notes/multi/console/MessageUtils.kt b/console/src/main/kotlin/notes/multi/console/MessageUtils.kt deleted file mode 100644 index 0cca4da0cf6c078ca2eb03be51a13f2cf35d2622..0000000000000000000000000000000000000000 --- a/console/src/main/kotlin/notes/multi/console/MessageUtils.kt +++ /dev/null @@ -1,10 +0,0 @@ -/* - * This Kotlin source file was generated by the Gradle 'init' task. - */ -package notes.multi.app - -class MessageUtils { - companion object { - fun getMessage(): String = "Hello World!" - } -} diff --git a/console/src/test/kotlin/notes/multi/app/MessageUtilsTest.kt b/console/src/test/kotlin/notes/multi/app/ConsoleUtilsTest.kt similarity index 82% rename from console/src/test/kotlin/notes/multi/app/MessageUtilsTest.kt rename to console/src/test/kotlin/notes/multi/app/ConsoleUtilsTest.kt index 19f65f6ce03b5b77c3aa3b30843ca332d58e83a1..c82975f9bc13d46389eadb34aadce7750b3095af 100644 --- a/console/src/test/kotlin/notes/multi/app/MessageUtilsTest.kt +++ b/console/src/test/kotlin/notes/multi/app/ConsoleUtilsTest.kt @@ -12,10 +12,7 @@ import notes.multi.utilities.Folder import java.time.LocalDate import java.time.LocalDateTime -class MessageUtilsTest { - @Test fun testGetMessage() { - assertEquals("Hello World!", MessageUtils.getMessage()) - } +class ConsoleUtilsTest { @Test fun checkModelClasses() { var n = Note( title = "NeverGonnaGiveYouUp", @@ -36,6 +33,6 @@ class MessageUtilsTest { notes = mutableListOf<Note>(n) ) - assertEquals(fldr.notes?.get(0) ?: null, n) + assertEquals(fldr.notes?.get(0), n) } } diff --git a/console/test.txt b/console/test.txt new file mode 100644 index 0000000000000000000000000000000000000000..b422493c74f367475aa4a6dac8441288a8281a4a --- /dev/null +++ b/console/test.txt @@ -0,0 +1 @@ +<html dir="ltr"><head></head><body contenteditable="true"><p><span style="font-family: "";">lambdaa!</span></p><p><span style="font-family: "";">aaaaaaa12312312312312</span></p></body></html> \ No newline at end of file diff --git a/console/test/asdasd.txt b/console/test/asdasd.txt new file mode 100644 index 0000000000000000000000000000000000000000..70a7416b25fe65127d78038704a7ec968ba8bb37 --- /dev/null +++ b/console/test/asdasd.txt @@ -0,0 +1 @@ +<html dir="ltr"><head></head><body contenteditable="true"><p><span style="font-family: "";">ASasAS</span></p></body></html> \ No newline at end of file diff --git a/console/test/test.txt b/console/test/test.txt new file mode 100644 index 0000000000000000000000000000000000000000..f73609a2f51cc2746bcb14325d5ab8d0524f34a2 --- /dev/null +++ b/console/test/test.txt @@ -0,0 +1 @@ +<html dir="ltr"><head></head><body contenteditable="true"><p><span style="font-family: "";">lambdaaaa!</span></p><p><span style="font-family: "";"><br></span></p></body></html> \ No newline at end of file diff --git a/console/test/testver2.txt b/console/test/testver2.txt index 98f0b76f4105bcffe84006178334459fba229ed6..2eae37aae9ba9a6e1fb06998d9ee6971bb4508f0 100644 --- a/console/test/testver2.txt +++ b/console/test/testver2.txt @@ -1 +1 @@ -<html dir="ltr"><head></head><body contenteditable="true"><p><span style="font-family: "";">Hello <span style="color: rgb(51, 77, 179);">my</span> <span style="background-color: rgb(26, 0, 104);">fried</span></span></p></body></html> \ No newline at end of file +<html dir="ltr"><head></head><body contenteditable="true"><p><span style="font-family: "";">Hello <span style="color: rgb(51, 77, 179);">my</span> <span style="background-color: rgb(26, 0, 104);">friedasdasdasd</span></span></p></body></html> \ No newline at end of file diff --git a/grades/team112-sprint1-demo.pdf b/grades/team112-sprint1-demo.pdf new file mode 100644 index 0000000000000000000000000000000000000000..100e2ce84e7c31c792a33cd42a9f945482009bbd Binary files /dev/null and b/grades/team112-sprint1-demo.pdf differ diff --git a/meeting-minutes/ds/20230209.md b/meeting-minutes/ds/20230209.md new file mode 100644 index 0000000000000000000000000000000000000000..81d76376b39615d8f75d58fa113a363856411ba4 --- /dev/null +++ b/meeting-minutes/ds/20230209.md @@ -0,0 +1,29 @@ +# CS 346: Daily Standup + +| Date | Team # | +|:----------:| :----: | +| 2023-02-09 | 112 | + +## Questions + +_Enter comments below. If a team member is absent, fill in their name, and put a line through the answer section_ + +| Name | What have you completed since last meeting? | What are you going to complete today? | What obstacles are in your way? | +| --------------- |---------------------------------------------|-----------------------------------------------|---------------------------------| +| Abhay Menon | - | #33 (Set up work for the next couple of days) | Waiting on Guransh and Anshul | +| Inseo Kim | - | #18, #19, #32 (for the next couple of days) | - | +| Hoang Dang | Completed all assigned tasks | - | - | +| Guransh Khurana | - | #31, #30 (for the next couple of days) | - | +| Anshul Ruhil | - | #20 (for the next couple of days) | - | + +## Outstanding + +_Do we need help with anything?_ + +No + +## Decisions + +_Is there anything else we should capture from this meeting?_ + +No diff --git a/meeting-minutes/ds/20230215.md b/meeting-minutes/ds/20230215.md new file mode 100644 index 0000000000000000000000000000000000000000..1a10b9833952bc381de4ff62dd3503be017ae41d --- /dev/null +++ b/meeting-minutes/ds/20230215.md @@ -0,0 +1,29 @@ +# CS 346: Daily Standup + +| Date | Team # | +|:----------:| :----: | +| 2023-02-09 | 112 | + +## Questions + +_Enter comments below. If a team member is absent, fill in their name, and put a line through the answer section_ + +| Name | What have you completed since last meeting? | What are you going to complete today? | What obstacles are in your way? | +| --------------- |---------------------------------------------|------------------------------------------------------|---------------------------------| +| Abhay Menon | Set up code for #33 | #33 (Depends on the completion of #31, #30, and #20) | Waiting on Guransh and Anshul | +| Inseo Kim | Completed all assigned tasks | - | - | +| Hoang Dang | Completed all assigned tasks | - | - | +| Guransh Khurana | - | #31, #30 | None | +| Anshul Ruhil | - | #20 | None | + +## Outstanding + +_Do we need help with anything?_ + +No + +## Decisions + +_Is there anything else we should capture from this meeting?_ + +No diff --git a/meeting-minutes/ds/20230216.md b/meeting-minutes/ds/20230216.md new file mode 100644 index 0000000000000000000000000000000000000000..2e97f9508237ccdff10a90aea4abfcd3f07067bc --- /dev/null +++ b/meeting-minutes/ds/20230216.md @@ -0,0 +1,29 @@ +# CS 346: Daily Standup + +| Date | Team # | +|:----------:| :----: | +| 2023-02-16 | 112 | + +## Questions + +_Enter comments below. If a team member is absent, fill in their name, and put a line through the answer section_ + +| Name | What have you completed since last meeting? | What are you going to complete today? | What obstacles are in your way? | +| --------------- |---------------------------------------------|-------------------------------------------------------------------------|-----------------------------------| +| Abhay Menon | Waiting on #31 and #20 completion | Working on #33 after Inseo finishes backlog created by #20, #30 and #31 | Waiting on #31 and #20 completion | +| Inseo Kim | Assisting Guransh with #30 and #31 | Finishing backlogged tasks #20, #30, and #31 | None | +| Hoang Dang | Completed all assigned tasks | - | - | +| Guransh Khurana | - | #31, #30 | Working with responsive heights | +| Anshul Ruhil | - | #20 | None | + +## Outstanding + +_Do we need help with anything?_ + +Will ask in Sprint Demo about warnings generated on running the console app + +## Decisions + +_Is there anything else we should capture from this meeting?_ + +No diff --git a/meeting-minutes/mm/20230208.md b/meeting-minutes/mm/20230208.md index 2ae6f032ee9f30d63fdb097c433822b85daab576..65da985c57566a0b423efc3a566377c84f08585f 100644 --- a/meeting-minutes/mm/20230208.md +++ b/meeting-minutes/mm/20230208.md @@ -24,6 +24,7 @@ Work for Sprint 1 will be assigned as follows: ## Decisions - The tasks will be distributed as mentioned above. +- Scrums shall be done two times a week. ## Actions - GitLab issues (that have already been created) have been assigned with appropriate priorities. \ No newline at end of file diff --git a/release-notes/1.0.0.md b/release-notes/1.0.0.md index 2a2c853cbf4024674a5c0d56925c556eed30642d..f2087587be2dcc3a4327421a0530c881e67caa33 100644 --- a/release-notes/1.0.0.md +++ b/release-notes/1.0.0.md @@ -1,23 +1,22 @@ # Team 112's Notes Application (Release 1.0.0) -> _Date: February 16, 2023_ +> _Date: February 17, 2023_ -## What's New +## 🚀 What's New -### From a Client's Perspective +### 👨ðŸ»â€ðŸ’¼ From a Client's Perspective With the new release of Team 112’s notes application, a user can: - Create a new note through the command line - Type some text in the basic GUI to be saved -- Use the toolbar/shortcuts to quit/save the file +- Use the shortcuts to quit/save the file - Edit an existing file from the command line -- Delete an existing file from the command line +- Delete an existing file -### From a Developer's Perspective -- Added unit tests to test the error bounds and edge cases of the application using JUnit 5 (specifications as per the course requirements) -- Added descriptive JDocs comments to significant code for easier documentation and code comprehension +### 👩ðŸ»â€ðŸ’» From a Developer's Perspective +- Added descriptive JavaDocs comments to significant code for easier documentation and code comprehension - Followed the MVC (Model-View-Controller) architectural pattern for developing the notes application - Created a GitLab events notifier into the team’s discord server to ping members for any changes caused by members in the repository -## Bug Fixes +## 🞠Bug Fixes None. diff --git a/utilities/src/main/kotlin/notes/multi/utilities/FileManager.kt b/utilities/src/main/kotlin/notes/multi/utilities/FileManager.kt new file mode 100644 index 0000000000000000000000000000000000000000..a346a2ca70b65c339d14e58677e53b4b9b836469 --- /dev/null +++ b/utilities/src/main/kotlin/notes/multi/utilities/FileManager.kt @@ -0,0 +1,61 @@ +package notes.multi.utilities + +import java.io.File +import java.io.InputStream + +/** + * Used for managing files within the notes application and performs create, delete, and edit operations on files + * @param dir Directory of the file + * @param name Name of the file + */ +class FileManager(private val dir: String, val name: String) { + private val directory = File(dir) + private val filepath = File("$dir/$name") + private val listFiles = mutableListOf<File>() + init { + for (f in directory.listFiles()!!) { + if (f.extension.lowercase() == "txt" || f.extension.lowercase() == "md") { + listFiles.add(f) + } + } + } + + /** + * Returns a list of mutable files + */ + fun files() : MutableList<File> { + return listFiles + } + + + /** + * Create file and write to it + */ + fun writeFile (line : String) { + filepath.writeText(line) + if (!listFiles.contains(filepath)) { + listFiles.add(filepath) + } + } + + /** + * Open and read existing file + */ + fun openFile(): String { + if (!listFiles.contains(filepath)) { + return "" + } + val inputStream: InputStream = filepath.inputStream() + + return inputStream.bufferedReader().use { it.readText() } + } + + /** + * Delete file + */ + fun deleteFile(): Boolean { + listFiles.remove(filepath) + return filepath.delete() + } + +} \ No newline at end of file diff --git a/utilities/src/main/kotlin/notes/multi/utilities/Filemanager.kt b/utilities/src/main/kotlin/notes/multi/utilities/Filemanager.kt deleted file mode 100644 index ffff0dba2ca137c58f84dac4cb702958042bbabc..0000000000000000000000000000000000000000 --- a/utilities/src/main/kotlin/notes/multi/utilities/Filemanager.kt +++ /dev/null @@ -1,47 +0,0 @@ -package notes.multi.utilities - -import java.io.File -import java.io.InputStream - -class Filemanager(private val dir: String, val name: String) { - private val directory = File(dir) - private val filepath = File("$dir/$name") - private val listfiles = mutableListOf<File>() - init { - for (f in directory.listFiles()!!) { - if (f.extension == "txt" || f.extension == "md") { - listfiles.add(f) - } - } - } - - //returns list of files - fun files() : MutableList<File> { - return listfiles - } - - - // create and write to that file - fun writefile(line:String) { - filepath.writeText(line) - if (!listfiles.contains(filepath)) { - listfiles.add(filepath) - } - } - - // opens and read the existing file - fun openfile(): String { - if (!listfiles.contains(filepath)) { - return "" - } - val inputStream: InputStream = filepath.inputStream() - - return inputStream.bufferedReader().use { it.readText() } - } - - fun deletefile():Boolean { - listfiles.remove(filepath) - return filepath.delete() - } - -} \ No newline at end of file diff --git a/utilities/src/main/kotlin/notes/multi/utilities/Folder.kt b/utilities/src/main/kotlin/notes/multi/utilities/Folder.kt index c958edc1739ac36c587d171e3633b32101fd6d58..af5d4fb47d313593294bef146c113e5d4d7fc798 100644 --- a/utilities/src/main/kotlin/notes/multi/utilities/Folder.kt +++ b/utilities/src/main/kotlin/notes/multi/utilities/Folder.kt @@ -3,13 +3,19 @@ package notes.multi.utilities import java.time.LocalDate import java.time.LocalDateTime +/** + * An abstract class denoting a Folder and all the relevant information about it + * @param title Title of the folder + * @param description Description of the folder + * @param author Author of the folder + * @param dateCreated Creation date of the folder + * @param lastModified Last modification date of the folder + * @param notes List of notes belonging to the folder + */ class Folder(var title: String = "Untitled", var description: String = "Empty", val author: String = "?", // User class? val dateCreated: LocalDate? = LocalDate.now(), var lastModified: LocalDateTime? = LocalDateTime.now(), var notes: MutableList<Note>? = null) { - - // add/remove notes - // update last modified } \ No newline at end of file diff --git a/utilities/src/main/kotlin/notes/multi/utilities/Note.kt b/utilities/src/main/kotlin/notes/multi/utilities/Note.kt index 97db5a681071bddff91d560afc2f34d5bee812bc..a523006d96ae025bf285b838fddd3bd1be9e6876 100644 --- a/utilities/src/main/kotlin/notes/multi/utilities/Note.kt +++ b/utilities/src/main/kotlin/notes/multi/utilities/Note.kt @@ -3,7 +3,16 @@ package notes.multi.utilities import java.time.LocalDate import java.time.LocalDateTime - +/** + * An abstract class denoting a Note and all the relevant information about it + * @param title Title of the note + * @param text Text/Content of the note + * @param author Author of the note + * @param extension File extension of the note + * @param dateCreated Creation date of the note + * @param lastModified Last modification date of the note + * @param location Location of the note + */ class Note(var title: String = "Untitled", var text: StringBuffer = StringBuffer(""), val author: String = "?", // User class? diff --git a/utilities/src/main/kotlin/notes/multi/utilities/NoteTextWindow.kt b/utilities/src/main/kotlin/notes/multi/utilities/NoteTextWindow.kt index fba66f1b9b838455c19b2fde07b70feb3575f9e4..48223379990eddcebc7dd599ee9c7a8a85b6f9dd 100644 --- a/utilities/src/main/kotlin/notes/multi/utilities/NoteTextWindow.kt +++ b/utilities/src/main/kotlin/notes/multi/utilities/NoteTextWindow.kt @@ -1,5 +1,4 @@ package notes.multi.utilities -import notes.multi.utilities.Filemanager import javafx.application.Application import javafx.stage.Stage @@ -8,7 +7,6 @@ import javafx.scene.control.ScrollPane import javafx.scene.control.TextArea import javafx.scene.layout.VBox import javafx.scene.layout.AnchorPane -import javafx.application.Application.Parameters import javafx.application.Platform import javafx.scene.Node import javafx.scene.control.Alert @@ -20,24 +18,40 @@ import javafx.scene.layout.Priority import javafx.scene.web.HTMLEditor import java.beans.EventHandler +/** + * - Displays a responsive `TextArea` in a window with the text of the file passed to the `Application.launch` function + * - Parameters are passed through the second parameter of the `Application.launch` in this format: + * ```kotlin + * Application.launch(TextWindow()::class.java, "--title=${fileTitle}", "--location=${fileLocation}") + * ``` + * @param title Name of the file to be accessed + * @param location Location of the file to be accessed + */ class TextWindow(): Application() { - var paramsMap = mutableMapOf<String, String>() + /** + * Map of params received by the `Application.Launch` function + * @see /console/src/main/kotlin/notes/multi/console/Console.kt + */ + private var paramsMap = mutableMapOf<String, String>() + /** + * Boolean value denoting whether console has been pressed + */ + private var controlPressed = false - var controlpressed = false override fun init() { super.init() - val params = getParameters() - paramsMap = params.getNamed() + val params = parameters + paramsMap = params.named } override fun start(stage: Stage) { val path = paramsMap["text"]!! - val filecontroller = Filemanager(path, paramsMap["title"]!!) + val filecontroller = FileManager(path, paramsMap["title"]!!) stage.setTitle(paramsMap["title"]) val textarea = HTMLEditor() //textarea.setText(paramsMap["text"]) - textarea.htmlText = filecontroller.openfile() + textarea.htmlText = filecontroller.openFile() //textarea.setWrapText(true) @@ -50,47 +64,50 @@ class TextWindow(): Application() { AnchorPane.setLeftAnchor(textarea, 0.0) AnchorPane.setRightAnchor(textarea, 0.0) - scroll.setFitToHeight(true) - scroll.setHmin(300.0) - scroll.setFitToWidth(true) - - // REMOVE THESE COMMENTS - // println("===========") - // println(scroll.isFitToHeight) - // println(scroll.isFitToWidth) + scroll.isFitToHeight = true + scroll.hmin = 300.0 + scroll.isFitToWidth = true + /** + * Responsive Design and scroll properties + */ scroll.content = textarea val box = VBox(anchor) VBox.setVgrow(anchor, Priority.ALWAYS) stage.scene = Scene(box, 300.0, 300.0) - + /** + * Logic for key presses: + * - Save: Ctrl + S + * - Delete: Ctrl + D + * - Close Window: Ctrl + W + */ stage.scene.setOnKeyPressed { event-> if (event.code == KeyCode.CONTROL) { - controlpressed = true - } else if (event.code == KeyCode.S && controlpressed) { + controlPressed = true + } else if (event.code == KeyCode.S && controlPressed) { val warning = Alert(Alert.AlertType.CONFIRMATION) warning.title = "SAVE" warning.contentText = "Do you want to save this file?" val result = warning.showAndWait() if (result.isPresent) { when (result.get()) { - ButtonType.OK -> filecontroller.writefile(textarea.htmlText) + ButtonType.OK -> filecontroller.writeFile(textarea.htmlText) } } - } else if (event.code == KeyCode.D && controlpressed) { + } else if (event.code == KeyCode.D && controlPressed) { val warning = Alert(Alert.AlertType.CONFIRMATION) warning.title = "DELETE" warning.contentText = "Do you delete this file?" val result = warning.showAndWait() if (result.isPresent) { when (result.get()) { - ButtonType.OK -> {filecontroller.deletefile() + ButtonType.OK -> {filecontroller.deleteFile() Platform.exit()} } } - } else if (event.code == KeyCode.W && controlpressed) { + } else if (event.code == KeyCode.W && controlPressed) { val warning = Alert(Alert.AlertType.CONFIRMATION) warning.title = "WARNING" warning.contentText = "The current work will not be saved. Are you sure you want to quit?" @@ -105,8 +122,11 @@ class TextWindow(): Application() { } } - stage.scene.setOnKeyReleased { event-> - if (controlpressed) {controlpressed = false} + /** + * Control press logic + */ + stage.scene.setOnKeyReleased { + if (controlPressed) {controlPressed = false} } diff --git a/utilities/src/test/kotlin/FileManagerTest.kt b/utilities/src/test/kotlin/FileManagerTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..b995b0e69eb05d395b928d9948b0e1d137ffbb7b --- /dev/null +++ b/utilities/src/test/kotlin/FileManagerTest.kt @@ -0,0 +1,22 @@ +import notes.multi.utilities.FileManager +import kotlin.test.Test +import kotlin.test.assertEquals + +internal class FileManagerTest { + private val testmanager: FileManager = FileManager("${System.getProperty("user.dir")}/testfolder/", "hello.txt") + + @Test + fun createreadfile() { + val expected = "hello from the moon" + testmanager.writeFile(expected) + assertEquals(expected, testmanager.openFile()) + } + + @Test + fun ReadNoneExistingFile() { + val expected = "" + testmanager.writeFile("walking to the mooon") + testmanager.deleteFile() + assertEquals(expected, testmanager.openFile()) + } +} \ No newline at end of file diff --git a/utilities/src/test/kotlin/FilemanagerTest.kt b/utilities/src/test/kotlin/FilemanagerTest.kt deleted file mode 100644 index e2eb36a473a7eb30a3036eec56f87ec3471e3f7b..0000000000000000000000000000000000000000 --- a/utilities/src/test/kotlin/FilemanagerTest.kt +++ /dev/null @@ -1,22 +0,0 @@ -import notes.multi.utilities.Filemanager -import kotlin.test.Test -import kotlin.test.assertEquals - -internal class FilemanagerTest { - private val testmanager: Filemanager = Filemanager("${System.getProperty("user.dir")}/testfolder/", "hello.txt") - - @Test - fun createreadfile() { - val expected = "hello from the moon" - testmanager.writefile(expected) - assertEquals(expected, testmanager.openfile()) - } - - @Test - fun ReadNoneExistingFile() { - val expected = "" - testmanager.writefile("walking to the mooon") - testmanager.deletefile() - assertEquals(expected, testmanager.openfile()) - } -} \ No newline at end of file