Started text note edition and notes explorer
This commit is contained in:
parent
ee4bdefc9d
commit
c06d95d22f
34
SmartNotes/src/com/madeorsk/smartnotes/ExplorerItem.java
Normal file
34
SmartNotes/src/com/madeorsk/smartnotes/ExplorerItem.java
Normal file
@ -0,0 +1,34 @@
|
||||
package com.madeorsk.smartnotes;
|
||||
|
||||
import com.madeorsk.smartnotes.notes.Note;
|
||||
import com.madeorsk.smartnotes.paths.FolderPath;
|
||||
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.HBox;
|
||||
|
||||
public class ExplorerItem extends HBox
|
||||
{
|
||||
private boolean folder;
|
||||
private Object item;
|
||||
|
||||
public ExplorerItem(boolean folder, Object item)
|
||||
{
|
||||
this.folder = folder;
|
||||
this.item = item;
|
||||
|
||||
if (this.folder)
|
||||
{
|
||||
FolderPath folderPath = (FolderPath) this.item;
|
||||
this.getChildren().add(new Label("FOLDER"));
|
||||
this.getChildren().add(new Label(folderPath.getName()));
|
||||
}
|
||||
else
|
||||
{
|
||||
Note note = (Note) this.item;
|
||||
Label img = new Label("NOTE");
|
||||
img.setTextFill(note.getNoteColor().getColor());
|
||||
this.getChildren().add(img);
|
||||
this.getChildren().add(new Label(note.getName()));
|
||||
}
|
||||
}
|
||||
}
|
98
SmartNotes/src/com/madeorsk/smartnotes/NotesExplorer.java
Normal file
98
SmartNotes/src/com/madeorsk/smartnotes/NotesExplorer.java
Normal file
@ -0,0 +1,98 @@
|
||||
package com.madeorsk.smartnotes;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import com.madeorsk.smartnotes.notes.Note;
|
||||
import com.madeorsk.smartnotes.paths.FolderPath;
|
||||
import com.madeorsk.smartnotes.paths.NotePath;
|
||||
import com.madeorsk.smartnotes.paths.Path;
|
||||
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
public class NotesExplorer extends VBox
|
||||
{
|
||||
private SavesManager saves;
|
||||
private Map<Integer, Note> notes;
|
||||
|
||||
private HBox titleBox;
|
||||
|
||||
public NotesExplorer()
|
||||
{
|
||||
this.saves = new SavesManager();
|
||||
this.notes = this.saves.loadIndex();
|
||||
this.titleBox = new HBox();
|
||||
{
|
||||
this.titleBox.getChildren().add(new Label("SmartNotes"));
|
||||
}
|
||||
this.updateList();
|
||||
}
|
||||
|
||||
private void updateList()
|
||||
{
|
||||
this.getChildren().clear();
|
||||
this.getChildren().add(this.titleBox);
|
||||
|
||||
FolderPath root = this.genRoot();
|
||||
for (Path p : root.getContent())
|
||||
{
|
||||
if (p.isFolder())
|
||||
{
|
||||
System.out.println("Folder : " + ((FolderPath) p).getName());
|
||||
this.getChildren().add(new ExplorerItem(true, p));
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println("Note : " + ((NotePath) p).getNoteId());
|
||||
this.getChildren().add(new ExplorerItem(false, this.notes.get(((NotePath) p).getNoteId())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private FolderPath genRoot()
|
||||
{
|
||||
FolderPath root = new FolderPath("/");
|
||||
for(int key : notes.keySet())
|
||||
{
|
||||
Note note = notes.get(key);
|
||||
for(String path : note.getPaths())
|
||||
{
|
||||
FolderPath putIn = root;
|
||||
String[] foldersString = (path.substring(1).contains("#")) ? path.substring(1).split("#") : Arrays.asList(path.substring(1)).toArray(new String[1]);
|
||||
for(String folderString : foldersString)
|
||||
{
|
||||
if (putIn.containsFolder(folderString))
|
||||
putIn = putIn.getFolder(folderString);
|
||||
else
|
||||
{
|
||||
FolderPath newFolder = new FolderPath(folderString);
|
||||
putIn.addPath(newFolder);
|
||||
putIn = newFolder;
|
||||
}
|
||||
}
|
||||
putIn.addPath(new NotePath(key));
|
||||
}
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
private int getNextId()
|
||||
{
|
||||
int i = 0;
|
||||
for(int key : notes.keySet())
|
||||
{
|
||||
if (key != i)
|
||||
return i;
|
||||
i++;
|
||||
}
|
||||
return notes.keySet().size();
|
||||
}
|
||||
|
||||
public void close()
|
||||
{
|
||||
this.saves.saveIndex(notes);
|
||||
}
|
||||
}
|
160
SmartNotes/src/com/madeorsk/smartnotes/SavesManager.java
Normal file
160
SmartNotes/src/com/madeorsk/smartnotes/SavesManager.java
Normal file
@ -0,0 +1,160 @@
|
||||
package com.madeorsk.smartnotes;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import com.madeorsk.smartnotes.notes.Note;
|
||||
|
||||
public class SavesManager
|
||||
{
|
||||
private static final String KEY = "Vivre et grandir à travers le commun";
|
||||
private static final File SAVE_FOLDER = new File("saves");
|
||||
|
||||
public SavesManager()
|
||||
{
|
||||
if (!SAVE_FOLDER.exists())
|
||||
SAVE_FOLDER.mkdirs();
|
||||
}
|
||||
|
||||
public void saveIndex(Map<Integer, Note> notes)
|
||||
{
|
||||
File indexFile = new File(SAVE_FOLDER, "index");
|
||||
if (indexFile.exists())
|
||||
indexFile.delete();
|
||||
|
||||
if (!notes.isEmpty())
|
||||
{
|
||||
String indexString = "";
|
||||
for(int key : notes.keySet())
|
||||
indexString += key + ":" + notes.get(key).getClass().getName() + "\n";
|
||||
|
||||
indexString = indexString.substring(0, indexString.length() - 1);
|
||||
this.writeFile(indexFile, indexString);
|
||||
}
|
||||
}
|
||||
public Map<Integer, Note> loadIndex()
|
||||
{
|
||||
File indexFile = new File(SAVE_FOLDER, "index");
|
||||
if (indexFile.exists())
|
||||
{
|
||||
Map<Integer, Note> notes = new HashMap<Integer, Note>();
|
||||
String indexString = this.readFile(indexFile);
|
||||
String[] notesString = indexString.split("\n");
|
||||
for(String noteString : notesString)
|
||||
{
|
||||
String[] decomposed = noteString.split(":");
|
||||
if (decomposed.length == 2)
|
||||
{
|
||||
try
|
||||
{
|
||||
Note note = (Note) this.getClass().getClassLoader().loadClass(decomposed[1]).newInstance();
|
||||
notes.put(Integer.parseInt(decomposed[0]), note);
|
||||
}
|
||||
catch (InstantiationException | IllegalAccessException | ClassNotFoundException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return notes;
|
||||
}
|
||||
else
|
||||
return new HashMap<Integer, Note>();
|
||||
}
|
||||
|
||||
public File getSaveFile(int id)
|
||||
{
|
||||
return new File(SAVE_FOLDER, id + "");
|
||||
}
|
||||
|
||||
public String readFile(File file)
|
||||
{
|
||||
try
|
||||
{
|
||||
FileInputStream fis = new FileInputStream(file);
|
||||
byte[] buffer = new byte[1024 * 8];
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
int n;
|
||||
while ((n = fis.read(buffer)) > 0)
|
||||
baos.write(buffer, 0, n);
|
||||
fis.close();
|
||||
|
||||
ByteArrayOutputStream stringBaos = new ByteArrayOutputStream();
|
||||
GZIPInputStream gzip = new GZIPInputStream(new ByteArrayInputStream(this.byteFpeDecryption(baos.toByteArray(), KEY)));
|
||||
while ((n = gzip.read(buffer)) > 0)
|
||||
stringBaos.write(buffer, 0, n);
|
||||
return new String(stringBaos.toByteArray());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
file.delete();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public void writeFile(File file, String content)
|
||||
{
|
||||
try
|
||||
{
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
GZIPOutputStream gzip = new GZIPOutputStream(baos);
|
||||
gzip.write(content.getBytes(), 0, content.getBytes().length);
|
||||
gzip.close();
|
||||
byte[] bytes = baos.toByteArray();
|
||||
|
||||
FileOutputStream fos = new FileOutputStream(file);
|
||||
fos.write(this.byteFpeEncryption(bytes, KEY));
|
||||
fos.flush();
|
||||
fos.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] byteFpeEncryption(byte[] bytes, String key)
|
||||
{
|
||||
String cipher = "";
|
||||
int i = 0;
|
||||
while (cipher.getBytes().length < bytes.length)
|
||||
{
|
||||
cipher += key.getBytes()[i];
|
||||
i++;
|
||||
if (i >= key.getBytes().length)
|
||||
i = 0;
|
||||
}
|
||||
|
||||
byte[] encryptedBytes = new byte[bytes.length];
|
||||
for(i = 0; i < bytes.length; i++)
|
||||
encryptedBytes[i] = (byte) (bytes[i] + cipher.getBytes()[i]);
|
||||
|
||||
return encryptedBytes;
|
||||
}
|
||||
private byte[] byteFpeDecryption(byte[] bytes, String key)
|
||||
{
|
||||
String cipher = "";
|
||||
int i = 0;
|
||||
while (cipher.getBytes().length < bytes.length)
|
||||
{
|
||||
cipher += key.getBytes()[i];
|
||||
i++;
|
||||
if (i >= key.getBytes().length)
|
||||
i = 0;
|
||||
}
|
||||
|
||||
byte[] decryptedBytes = new byte[bytes.length];
|
||||
for(i = 0; i < bytes.length; i++)
|
||||
decryptedBytes[i] = (byte) (bytes[i] - cipher.getBytes()[i]);
|
||||
|
||||
return decryptedBytes;
|
||||
}
|
||||
}
|
@ -1,9 +1,12 @@
|
||||
package com.madeorsk.smartnotes;
|
||||
|
||||
import javafx.application.Application;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.text.Font;
|
||||
import javafx.stage.Stage;
|
||||
import javafx.stage.WindowEvent;
|
||||
|
||||
public class SmartNotes extends Application
|
||||
{
|
||||
@ -12,18 +15,38 @@ public class SmartNotes extends Application
|
||||
public static void main(String[] args)
|
||||
{
|
||||
System.out.println("Starting SmartNotes...");
|
||||
System.setProperty("prism.lcdtext", "false");
|
||||
launch();
|
||||
System.out.println("SmartNotes closed.");
|
||||
}
|
||||
|
||||
private Scene scene;
|
||||
private VBox root;
|
||||
|
||||
@Override
|
||||
public void start(Stage stage) throws Exception
|
||||
{
|
||||
this.root = new VBox();
|
||||
Font.loadFont(this.getClass().getResourceAsStream("/com/madeorsk/smartnotes/res/CutiveMono-Regular.ttf"), 10);
|
||||
|
||||
stage.setScene(new Scene(this.root, 800, 600));
|
||||
this.root = new VBox();
|
||||
this.root.setStyle("-fx-background-color: #282828;");
|
||||
|
||||
NotesExplorer explorer = new NotesExplorer();
|
||||
this.root.getChildren().add(explorer);
|
||||
|
||||
this.scene = new Scene(this.root, 800, 600);
|
||||
this.scene.getStylesheets().add("/com/madeorsk/smartnotes/style.css");
|
||||
|
||||
stage.setOnCloseRequest(new EventHandler<WindowEvent>()
|
||||
{
|
||||
@Override
|
||||
public void handle(WindowEvent e)
|
||||
{
|
||||
explorer.close();
|
||||
}
|
||||
});
|
||||
|
||||
stage.setScene(this.scene);
|
||||
stage.setTitle("SmartNotes " + version);
|
||||
stage.show();
|
||||
}
|
||||
|
60
SmartNotes/src/com/madeorsk/smartnotes/notes/Note.java
Normal file
60
SmartNotes/src/com/madeorsk/smartnotes/notes/Note.java
Normal file
@ -0,0 +1,60 @@
|
||||
package com.madeorsk.smartnotes.notes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.paint.Color;
|
||||
|
||||
public abstract class Note
|
||||
{
|
||||
public enum NoteColor
|
||||
{
|
||||
WHITE(255, 255, 255),
|
||||
BLUE(0, 0, 0),
|
||||
YELLOW(0, 0, 0),
|
||||
RED(0, 0, 0),
|
||||
GREEN(0, 0, 0);
|
||||
|
||||
private double r;
|
||||
private double g;
|
||||
private double b;
|
||||
NoteColor(double red, double green, double blue)
|
||||
{
|
||||
this.r = red;
|
||||
this.g = green;
|
||||
this.b = blue;
|
||||
}
|
||||
public Color getColor()
|
||||
{
|
||||
return new Color(this.r, this.g, this.b, 1);
|
||||
}
|
||||
}
|
||||
|
||||
private String name;
|
||||
private NoteColor color = NoteColor.WHITE;
|
||||
protected List<String> paths;
|
||||
|
||||
public void setName(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
public String getName()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setNoteColor(NoteColor color)
|
||||
{
|
||||
this.color = color;
|
||||
}
|
||||
public NoteColor getNoteColor()
|
||||
{
|
||||
return this.color;
|
||||
}
|
||||
public List<String> getPaths()
|
||||
{
|
||||
return this.paths;
|
||||
}
|
||||
|
||||
public abstract VBox getNoteBox();
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.madeorsk.smartnotes.notes;
|
||||
|
||||
import com.madeorsk.smartnotes.SavesManager;
|
||||
|
||||
public interface SavableNote
|
||||
{
|
||||
public void save(SavesManager saves, int id);
|
||||
public void load(SavesManager saves, int id);
|
||||
}
|
93
SmartNotes/src/com/madeorsk/smartnotes/notes/TextNote.java
Normal file
93
SmartNotes/src/com/madeorsk/smartnotes/notes/TextNote.java
Normal file
@ -0,0 +1,93 @@
|
||||
package com.madeorsk.smartnotes.notes;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
import com.madeorsk.smartnotes.SavesManager;
|
||||
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
public class TextNote extends Note implements SavableNote
|
||||
{
|
||||
private String content;
|
||||
|
||||
public TextNote()
|
||||
{
|
||||
this.setName("Text_" + Calendar.YEAR + "." + Calendar.MONTH + "." + Calendar.DAY_OF_MONTH + "-" + Calendar.HOUR_OF_DAY + ":" + Calendar.MINUTE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VBox getNoteBox()
|
||||
{
|
||||
VBox box = new VBox();
|
||||
box.setFillWidth(true);
|
||||
|
||||
HBox titleBox = new HBox();
|
||||
{
|
||||
// TODO Title box
|
||||
}
|
||||
box.getChildren().add(titleBox);
|
||||
|
||||
TextField nameField = new TextField();
|
||||
{
|
||||
nameField.setAlignment(Pos.CENTER);
|
||||
nameField.setId("nameField");
|
||||
nameField.setText(this.getName());
|
||||
}
|
||||
box.getChildren().add(nameField);
|
||||
|
||||
TextArea textArea = new TextArea();
|
||||
{
|
||||
textArea.setId("textArea");
|
||||
textArea.setWrapText(true);
|
||||
textArea.prefHeightProperty().bind(box.heightProperty().subtract(nameField.heightProperty()).subtract(titleBox.heightProperty()));
|
||||
textArea.setText(this.getContent());
|
||||
}
|
||||
box.getChildren().add(textArea);
|
||||
|
||||
return box;
|
||||
}
|
||||
|
||||
public void setContent(String content)
|
||||
{
|
||||
this.content = content;
|
||||
this.updatePaths();
|
||||
}
|
||||
public String getContent()
|
||||
{
|
||||
return this.content;
|
||||
}
|
||||
|
||||
private void updatePaths()
|
||||
{
|
||||
String text = this.getContent();
|
||||
if (text.contains("\n"))
|
||||
{
|
||||
String[] lines = text.split("\n");
|
||||
String lastLine = lines[lines.length - 1];
|
||||
for(String word : lastLine.split(" "))
|
||||
if (word.startsWith("#") && !word.equals("#"))
|
||||
this.paths.add(word);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(String word : text.split(" "))
|
||||
if (word.startsWith("#") && !word.equals("#"))
|
||||
this.paths.add(word);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(SavesManager saves, int id)
|
||||
{
|
||||
saves.writeFile(saves.getSaveFile(id), this.getContent());
|
||||
}
|
||||
@Override
|
||||
public void load(SavesManager saves, int id)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
}
|
52
SmartNotes/src/com/madeorsk/smartnotes/paths/FolderPath.java
Normal file
52
SmartNotes/src/com/madeorsk/smartnotes/paths/FolderPath.java
Normal file
@ -0,0 +1,52 @@
|
||||
package com.madeorsk.smartnotes.paths;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class FolderPath implements Path
|
||||
{
|
||||
private String name;
|
||||
private List<Path> content = new ArrayList<Path>();
|
||||
|
||||
public FolderPath(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void addPath(Path path)
|
||||
{
|
||||
this.content.add(path);
|
||||
}
|
||||
|
||||
public FolderPath getFolder(String folderName)
|
||||
{
|
||||
for(Path path : this.content)
|
||||
if (path.isFolder())
|
||||
if (((FolderPath) path).getName().equalsIgnoreCase(folderName))
|
||||
return (FolderPath) path;
|
||||
return null;
|
||||
}
|
||||
public boolean containsFolder(String folderName)
|
||||
{
|
||||
for(Path path : this.content)
|
||||
if (path.isFolder())
|
||||
if (((FolderPath) path).getName().equalsIgnoreCase(folderName))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
public List<Path> getContent()
|
||||
{
|
||||
return this.content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFolder()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
22
SmartNotes/src/com/madeorsk/smartnotes/paths/NotePath.java
Normal file
22
SmartNotes/src/com/madeorsk/smartnotes/paths/NotePath.java
Normal file
@ -0,0 +1,22 @@
|
||||
package com.madeorsk.smartnotes.paths;
|
||||
|
||||
public class NotePath implements Path
|
||||
{
|
||||
private int noteId;
|
||||
|
||||
public NotePath(int id)
|
||||
{
|
||||
this.noteId = id;
|
||||
}
|
||||
|
||||
public int getNoteId()
|
||||
{
|
||||
return this.noteId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFolder()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
6
SmartNotes/src/com/madeorsk/smartnotes/paths/Path.java
Normal file
6
SmartNotes/src/com/madeorsk/smartnotes/paths/Path.java
Normal file
@ -0,0 +1,6 @@
|
||||
package com.madeorsk.smartnotes.paths;
|
||||
|
||||
public interface Path
|
||||
{
|
||||
public boolean isFolder();
|
||||
}
|
Binary file not shown.
33
SmartNotes/src/com/madeorsk/smartnotes/style.css
Normal file
33
SmartNotes/src/com/madeorsk/smartnotes/style.css
Normal file
@ -0,0 +1,33 @@
|
||||
.scroll-bar
|
||||
{
|
||||
-fx-background-color: #282828;
|
||||
}
|
||||
.scroll-bar .increment-button, .scroll-bar .decrement-button, .scroll-bar .increment-button .increment-arrow, .scroll-bar .decrement-button .decrement-arrow
|
||||
{
|
||||
-fx-font-size: 0;
|
||||
-fx-padding: 0;
|
||||
}
|
||||
.scroll-bar .track
|
||||
{
|
||||
-fx-background-color: transparent;
|
||||
}
|
||||
.scroll-bar .thumb
|
||||
{
|
||||
-fx-background-color: rgba(0, 0, 0, 0.15);
|
||||
-fx-border-radius: 0;
|
||||
}
|
||||
|
||||
#nameField, .scroll-pane, .scroll-pane .viewport, #textArea, #textArea .content
|
||||
{
|
||||
-fx-background-color: transparent;
|
||||
}
|
||||
#nameField, #textArea
|
||||
{
|
||||
-fx-text-fill: white;
|
||||
-fx-font-family: 'Cutive Mono';
|
||||
-fx-font-size: 32px;
|
||||
}
|
||||
#textArea
|
||||
{
|
||||
-fx-font-size: 20px;
|
||||
}
|
Loading…
Reference in New Issue
Block a user