package org.blueshard.cryptogx; import javafx.application.Platform; import javafx.collections.FXCollections; import javafx.event.Event; import javafx.fxml.Initializable; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.Menu; import javafx.scene.control.MenuBar; import javafx.scene.control.MenuItem; import javafx.scene.control.ScrollPane; import javafx.scene.control.TextArea; import javafx.scene.control.TextField; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.input.*; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.VBox; import javafx.stage.*; import javax.crypto.BadPaddingException; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.imageio.ImageIO; import java.awt.*; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.image.BufferedImage; import java.io.*; import java.net.*; import java.nio.charset.StandardCharsets; import java.nio.file.CopyOption; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.spec.InvalidKeySpecException; import java.util.*; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import static org.blueshard.cryptogx.Settings.*; import static org.blueshard.cryptogx.Main.*; public class Controller implements Initializable { private Event fileEnDecryptLabelEvent; private double menubarX, menubarY; private boolean textLoading = false; private boolean fileEnDecryptLoading = false; private boolean fileDeleteLoading = false; private final AtomicInteger textThreads = new AtomicInteger(0); private final AtomicInteger totalThreads = new AtomicInteger(0); private final int tooltipShow = 15; private final int DATAFILEURL = 2; private final int FILEFILEURL = 1; private final int NONSPECIFICFILEURL = 0; private final byte[] buffer = new byte[64]; private final KeyCombination paste = new KeyCodeCombination(KeyCode.V, KeyCombination.CONTROL_DOWN); private final Image loadingImage = new Image(getClass().getResource("resources/loading.gif").toExternalForm()); private HashMap currentConfigSettings = new HashMap<>(); private final HashMap> enDecryptInputOutputFiles = new HashMap<>(); private final HashMap> enDecryptInputOutputInternetFiles = new HashMap<>(); private final HashMap enDecryptInputOutputClipboardImages = new HashMap<>(); private final HashMap deleteInputFiles = new HashMap<>(); private final List fileEnDecryptThreads = Collections.synchronizedList(new ArrayList<>()); private final List fileDeleteThreads = Collections.synchronizedList(new ArrayList<>()); private final ContextMenu fileEnDecryptInputContextMenu = new ContextMenu(); private final ContextMenu fileDeleteInputContextMenu = new ContextMenu(); private Label choosedLabel = null; private String choosedLabelType = null; private final MenuItem fileOutputFileChangeDest = new MenuItem("Change output file"); private final MenuItem getChoosedLabelInputFileFolder = new MenuItem("Open source directory"); private final MenuItem getChoosedLabelOutputFileFolder = new MenuItem("Open source directory"); private final Tooltip tooltip = new Tooltip(); public AnchorPane rootWindow; public Button fileEnDecryptFilesButton; public Button fileDecrypt; public Button fileEncrypt; public Button fileEnDecryptStop; public ComboBox textAlgorithmBox; public ComboBox fileEnDecryptAlgorithmBox; public ImageView minimizeWindow; public ImageView closeWindow; public ImageView textLoadingImage; public ImageView fileEnDecryptLoadingImage; public ImageView fileDeleteLoadingImage; public Menu settingsMenu; public Menu helpMenu; public MenuBar menubar; public MenuItem setDefaultOutputPath; public MenuItem saveSettings; public MenuItem loadSettings; public MenuItem exportSettings; public MenuItem importSettings; public RadioMenuItem removeFileFromFileBox; public RadioMenuItem limitNumberOfThreads; public ScrollPane fileEnDecryptInputScroll; public TextArea textDecryptedEntry; public TextArea textEncryptedEntry; public TextField textKeyEntry; public TextField textSaltEntry; public TextField fileEnDecryptKeyEntry; public TextField fileDecryptOutputFile; public TextField fileEncryptOutputFile; public TextField fileEnDecryptSaltEntry; public TextField fileDeleteIterationsEntry; public VBox fileEnDecryptInputFiles; public VBox fileDeleteInputFiles; //-----general-----// /** *

Shows a tooltip when the user type in some text in a text field, text area, etc. and the mouse is over this entry

* * @param event from which this method is called */ public void keyTypedTooltip(KeyEvent event) { String id = null; String text = ""; try { id = ((TextField) event.getSource()).getId(); text = ((TextField) event.getSource()).getText() + event.getCharacter(); tooltip.setText(text); } catch (ClassCastException e) { tooltip.setText(((TextArea) event.getSource()).getText() + event.getCharacter()); } if (id != null) { switch (id) { case ("textKeyEntry"): currentConfigSettings.replace("textKey", text); break; case ("textSaltEntry"): currentConfigSettings.replace("textSalt", text); break; case ("fileEnDecryptKeyEntry"): currentConfigSettings.replace("fileEnDecryptKey", text); break; case ("fileEnDecryptSaltEntry"): currentConfigSettings.replace("fileEnDecryptSalt", text); break; case ("fileDeleteIterationsEntry"): currentConfigSettings.replace("fileDeleteIterations", String.valueOf(Integer.parseInt(text))); break; } } } /** *

Shows a tooltip when to mouse is over a text field, text area, etc.

* * @param event from which this method is called */ public void mouseOverEntryTooltip(MouseEvent event) { try { tooltip.setText(((TextField) event.getSource()).getText()); } catch (ClassCastException e) { try { tooltip.setText(((TextArea) event.getSource()).getText()); } catch (ClassCastException ex) { tooltip.setText(((Label) event.getSource()).getText()); } } if (!tooltip.getText().trim().isEmpty()) { tooltip.show(rootWindow.getScene().getWindow(), event.getScreenX(), event.getScreenY() + tooltipShow); } } /** *

Hides the tooltip if the mouse exit a text field, text area, etc.

*/ public void mouseExitEntryTooltip() { tooltip.hide(); } //-----menu / close bar-----// /** *

Closed the application. * Get called if red close button is pressed

* * @since 1.0.0 */ public void closeApplication() { Stage rootStage = (Stage) rootWindow.getScene().getWindow(); rootStage.close(); System.exit(0); } /** *

Hides the application. * Get called if the green minimize button is pressed

* * @since 1.0.0 */ public void minimizeApplication() { Stage rootStage = (Stage) rootWindow.getScene().getWindow(); rootStage.setIconified(true); } //-----text-----// /** *

Encrypt text in {@link Controller#textDecryptedEntry}. * Get called if the text 'Encrypt' button is pressed

* * @since 1.0.0 */ public void textEncryptButton() { final byte[] salt; if (!textSaltEntry.getText().isEmpty()) { salt = textSaltEntry.getText().getBytes(StandardCharsets.UTF_8); } else { salt = new byte[16]; } if (!textLoading) { textLoadingImage.setImage(loadingImage); } Thread textEncrypt = new Thread(() -> { textThreads.getAndIncrement(); if (limitNumberOfThreads.isSelected()) { while (totalThreads.get() >= Runtime.getRuntime().availableProcessors()) { try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().stop(); } } } totalThreads.getAndIncrement(); String textAlgorithm = textAlgorithmBox.getSelectionModel().getSelectedItem(); EnDecrypt.AES encrypt = new EnDecrypt.AES(textKeyEntry.getText(), salt, Integer.parseInt(textAlgorithm.substring(textAlgorithm.indexOf('-') + 1))); try { String encryptedText = encrypt.encrypt(textDecryptedEntry.getText()); Platform.runLater(() -> textEncryptedEntry.setText(encryptedText)); } catch (NoSuchPaddingException | InvalidKeySpecException | InvalidKeyException | NoSuchAlgorithmException | BadPaddingException e) { e.printStackTrace(); } catch (IllegalArgumentException | IllegalBlockSizeException e) { e.printStackTrace(); Platform.runLater(() -> errorAlert("Wrong text for encryption is given", e.getMessage())); } if ((textThreads.get() - 1) <= 0) { textLoadingImage.setImage(null); textLoading = false; } textThreads.getAndDecrement(); totalThreads.getAndDecrement(); }); textEncrypt.setDaemon(false); textEncrypt.start(); textLoading = true; } /** *

Decrypt text in {@link Controller#textEncryptedEntry}. * Get called if the text 'Decrypt' button is pressed

* * @since 1.0.0 */ public void textDecryptButton() { final byte[] salt; if (!textSaltEntry.getText().isEmpty()) { salt = textSaltEntry.getText().getBytes(StandardCharsets.UTF_8); } else { salt = new byte[16]; } if (!textLoading) { textLoadingImage.setImage(loadingImage); } Thread textDecrypt = new Thread(() -> { textThreads.getAndIncrement(); if (limitNumberOfThreads.isSelected()) { while (totalThreads.get() >= Runtime.getRuntime().availableProcessors()) { try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().stop(); } } } totalThreads.getAndIncrement(); String textAlgorithm = textAlgorithmBox.getSelectionModel().getSelectedItem(); EnDecrypt.AES decrypt = new EnDecrypt.AES(textKeyEntry.getText(), salt, Integer.parseInt(textAlgorithm.substring(textAlgorithm.indexOf('-') + 1))); try { String DecryptedText = decrypt.decrypt(textEncryptedEntry.getText()); Platform.runLater(() -> textDecryptedEntry.setText(DecryptedText)); } catch (NoSuchPaddingException | InvalidKeySpecException | InvalidKeyException | NoSuchAlgorithmException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); Platform.runLater(() -> errorAlert("Wrong key and / or salt is given", e.getMessage())); } catch (IllegalArgumentException | IllegalBlockSizeException e) { e.printStackTrace(); Platform.runLater(() -> errorAlert("Wrong text for decryption is given", e.getMessage())); } if ((textThreads.get() - 1) <= 0) { textLoading = false; Platform.runLater(() -> textLoadingImage.setImage(null)); } textThreads.getAndDecrement(); totalThreads.getAndDecrement(); }); textDecrypt.setDaemon(false); textDecrypt.start(); textLoading = true; } //-----fileEnDecrypt-----// /** *

Synchronized method to get the list of threads which en- / decrypt files

* * @return list of en- / decryption threads */ private synchronized List getFileEnDecryptThreads() { return fileEnDecryptThreads; } /** *

Synchronized method to get the number of threads which en- / decrypt files

* * @return number of en- / decryption threads * * @since 1.2.0 */ private synchronized int getFileEnDecryptThreadsSize() { return fileEnDecryptThreads.size(); } /** *

Synchronized method to add a thread to the file en- / decryption list of current running file en- / decryption threads

* * @param thread that should be added * * @since 1.2.0 */ private synchronized void addFileEnDecryptThread(Thread thread) { fileEnDecryptThreads.add(thread); } /** *

Synchronized method to remove a thread from the file en- / decryption list of current running file en- / decryption threads

* * @param thread that should be removed * * @since 1.2.0 */ private synchronized void removeFileEnDecryptThread(Thread thread) { fileEnDecryptThreads.remove(thread); } /** *

Adds a file for en- / decryption

* * @param file that should be added * * @since 1.0.0 */ private void fileEnDecryptAddFile(File file) { for (Label l: enDecryptInputOutputFiles.keySet()) { if (l.getText().equals(file.getAbsolutePath())) { return; } } Label newLabel = new Label(file.getAbsolutePath()); newLabel.setOnKeyTyped(this::keyTypedTooltip); newLabel.setOnMouseMoved(this::mouseOverEntryTooltip); newLabel.setOnMouseExited(event -> mouseExitEntryTooltip()); newLabel.setOnMouseClicked(event -> { fileEnDecryptSelected(newLabel); fileOutputFilesChangeText(newLabel, null, null); fileEnDecryptLabelEvent = event; }); newLabel.setContextMenu(fileEnDecryptInputContextMenu); String fileAbsolutePath = file.getAbsolutePath(); String fileName = file.getName(); File encryptFile; File decryptFile; String fileOutputPath = file.getParent() + "/";; String fileEnding; ArrayList inputOutputList = new ArrayList<>(); if (!currentConfigSettings.get("fileOutputPath").trim().isEmpty()) { fileOutputPath = currentConfigSettings.get("fileOutputPath").trim() + "/"; } if (file.isFile()) { fileEnding = ".cryptoGX"; } else { fileEnding = "_cryptoGX"; } encryptFile = new File(fileOutputPath + fileName + fileEnding); while (encryptFile.exists()) { encryptFile = new File(encryptFile.getAbsolutePath() + fileEnding); } if (fileAbsolutePath.endsWith(".cryptoGX") || fileAbsolutePath.endsWith("_cryptoGX")) { decryptFile = new File(fileOutputPath + fileName.substring(0, fileName.length() - 9)); } else { decryptFile = new File(fileOutputPath + fileName + fileEnding); } while (decryptFile.exists()) { decryptFile = new File(decryptFile.getAbsolutePath() + fileEnding); } inputOutputList.add(0, encryptFile); inputOutputList.add(1, decryptFile); fileEnDecryptInputFiles.getChildren().add(newLabel); enDecryptInputOutputFiles.put(newLabel, inputOutputList); } /** *

Adds an file from the internet for en- / decryption

* * @param url of the file * @param fileType of the file * @throws URISyntaxException * * @since 1.5.0 */ private void fileEnDecryptAddInternetFile(String url, int fileType) throws URISyntaxException { String filename; switch (fileType) { case FILEFILEURL: filename = url.substring(url.lastIndexOf("/") + 1); break; case DATAFILEURL: filename = url.substring(5, url.indexOf("/")) + "." + url.substring(url.indexOf("/") + 1, url.indexOf(";")); break; case NONSPECIFICFILEURL: filename = "unknown" + System.nanoTime(); break; default: warningAlert("Cannot read given url '" + url + "'"); return; } for (Label l: enDecryptInputOutputInternetFiles.keySet()) { if (l.getText().equals(filename)) { return; } } Label newLabel = new Label(filename); newLabel.setOnKeyTyped(this::keyTypedTooltip); newLabel.setOnMouseMoved(this::mouseOverEntryTooltip); newLabel.setOnMouseExited(event -> mouseExitEntryTooltip()); newLabel.setOnMouseClicked(event -> { fileEnDecryptSelected(newLabel); fileOutputFilesChangeText(newLabel, null, null); fileEnDecryptLabelEvent = event; }); newLabel.setContextMenu(fileEnDecryptInputContextMenu); File encryptFile; File decryptFile; ArrayList fileSpecs = new ArrayList<>(); ArrayList inputOutputFiles = new ArrayList<>(); fileSpecs.add(0, fileType); fileSpecs.add(1, url); String currentDir = this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath(); if (currentConfigSettings.get("fileOutputPath").trim().isEmpty()) { encryptFile = new File(currentDir + "/" + filename + ".cryptoGX"); while (encryptFile.isFile()) { encryptFile = new File(encryptFile.getAbsolutePath() + ".cryptoGX"); } if (url.endsWith(".cryptoGX") && filename.endsWith(".cryptoGX")) { decryptFile = new File(currentDir + "/" + filename.substring(0, filename.length() - 9)); } else { decryptFile = new File(currentDir + "/" + filename); } } else { encryptFile = new File(currentConfigSettings.get("fileOutputPath") + "/" + filename + ".cryptoGX"); while (encryptFile.isFile()) { encryptFile = new File(encryptFile.getAbsolutePath() + ".cryptoGX"); } if (url.endsWith(".cryptoGX") && filename.endsWith(".cryptoGX")) { decryptFile = new File(currentConfigSettings.get("fileOutputPath") + "/" + filename.substring(0, filename.length() - 9)); } else { decryptFile = new File(currentConfigSettings.get("fileOutputPath") + "/" + filename); } } while (decryptFile.isFile()) { decryptFile = new File(decryptFile.getAbsolutePath() + ".cryptoGX"); } inputOutputFiles.add(0, encryptFile); inputOutputFiles.add(1, decryptFile); fileEnDecryptInputFiles.getChildren().add(newLabel); enDecryptInputOutputInternetFiles.put(newLabel, fileSpecs); enDecryptInputOutputFiles.put(newLabel, inputOutputFiles); } /** *

Adds an clipboard image for en- / decryption. * This can be a normal image and an image stream

* * @param image that should be added * @throws URISyntaxException * * @since 1.7.0 */ private void fileEnDecryptAddClipboardImage(BufferedImage image) throws URISyntaxException { String filename = "clipboardImage" + System.nanoTime() + ".png"; for (Label l: enDecryptInputOutputClipboardImages.keySet()) { if (l.getText().equals(filename)) { return; } } Label newLabel = new Label(filename); newLabel.setOnKeyTyped(this::keyTypedTooltip); newLabel.setOnMouseMoved(this::mouseOverEntryTooltip); newLabel.setOnMouseExited(event -> mouseExitEntryTooltip()); newLabel.setOnMouseClicked(event -> { fileEnDecryptSelected(newLabel); fileOutputFilesChangeText(newLabel, null, null); fileEnDecryptLabelEvent = event; }); newLabel.setContextMenu(fileEnDecryptInputContextMenu); File encryptFile; File decryptFile; String currentDir = this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath(); ArrayList inputOutputFiles = new ArrayList<>(); if (currentConfigSettings.get("fileOutputPath").trim().isEmpty()) { encryptFile = new File(currentDir + "/" + filename + ".cryptoGX"); decryptFile = new File(currentDir + "/" + filename); } else { encryptFile = new File(currentConfigSettings.get("fileOutputPath").trim() + "/" + filename + ".cryptoGX"); decryptFile = new File(currentConfigSettings.get("fileOutputPath").trim() + "/" + filename); } while (encryptFile.isFile()) { encryptFile = new File(encryptFile.getAbsolutePath() + ".cryptoGX"); } while (decryptFile.isFile()) { decryptFile = new File(decryptFile.getAbsolutePath() + ".cryptoGX"); } inputOutputFiles.add(0, encryptFile); inputOutputFiles.add(1, decryptFile); fileEnDecryptInputFiles.getChildren().add(newLabel); enDecryptInputOutputClipboardImages.put(newLabel, image); enDecryptInputOutputFiles.put(newLabel, inputOutputFiles); } /** *

Changes the text in the file en- / decryption output file text fields

* * @param label * @param encryptOutputFile is the filename of the file it gets encrypted * @param decryptOutputFile is the filename of the file it gets decrypted * * @since 1.2.0 */ private void fileOutputFilesChangeText(Label label, String encryptOutputFile, String decryptOutputFile) { File encryptFile; File decryptFile; ArrayList change = new ArrayList<>(); if (encryptOutputFile == null) { encryptFile = enDecryptInputOutputFiles.get(label).get(0); } else { encryptFile = new File(encryptOutputFile); } if (decryptOutputFile == null) { decryptFile = enDecryptInputOutputFiles.get(label).get(1); } else { decryptFile = new File(decryptOutputFile); } change.add(0, encryptFile); change.add(1, decryptFile); if (encryptFile.toString().trim().isEmpty()) { fileEncryptOutputFile.setText(""); } else { fileEncryptOutputFile.setText(encryptFile.getAbsolutePath()); } if (decryptFile.toString().trim().isEmpty()) { fileDecryptOutputFile.setText(""); } else { fileDecryptOutputFile.setText(decryptFile.getAbsolutePath()); } enDecryptInputOutputFiles.replace(label, change); } /** *

Deletes an entry for en- / decryption. * Get called if the user presses 'del' or delete the entry in the en- / decryption box via the right click tooltip

* * @param label that should be deleted * * @since 1.2.0 */ private void fileEnDecryptDeleteEntry(Label label) { enDecryptInputOutputFiles.remove(label); if (fileEnDecryptInputFiles.getChildren().size() - 1 >= 1) { for (int i = 0; i < fileEnDecryptInputFiles.getChildren().size(); i++) { if (fileEnDecryptInputFiles.getChildren().get(i) == label) { fileEnDecryptInputFiles.getChildren().remove(label); if (label == choosedLabel) { try { choosedLabel = (Label) fileEnDecryptInputFiles.getChildren().get(i - 1); choosedLabelType = "ENDECRYPT"; fileOutputFilesChangeText(choosedLabel, null, null); fileEnDecryptSelected(choosedLabel); } catch (ArrayIndexOutOfBoundsException e) { e.printStackTrace(); fileOutputFileChangeDest.setDisable(true); getChoosedLabelOutputFileFolder.setDisable(true); fileEncryptOutputFile.setEditable(false); fileDecryptOutputFile.setEditable(false); fileOutputFilesChangeText(choosedLabel, "", ""); choosedLabel = null; choosedLabelType = null; } break; } } } } else { fileEnDecryptInputFiles.getChildren().remove(label); fileOutputFileChangeDest.setDisable(true); getChoosedLabelOutputFileFolder.setDisable(true); fileEncryptOutputFile.setEditable(false); fileDecryptOutputFile.setEditable(false); if (label == choosedLabel) { fileOutputFilesChangeText(choosedLabel, "", ""); choosedLabel = null; choosedLabelType = null; } } } /** *

Changes the highlight of the clicked item in the en- / decryption box. * Get called if the user click an non-highlighted item in the en- / decryption box

* * @param changeLabel is the label that the user has clicked * * @since 1.0.0 */ private void fileEnDecryptSelected(Label changeLabel) { if (changeLabel != null) { fileDeleteSelected(null); enDecryptInputOutputFiles.keySet().forEach(label -> label.setStyle(null)); changeLabel.setStyle("-fx-background-color: lightblue; -fx-border-color: #292929"); fileDecryptOutputFile.setEditable(true); fileEncryptOutputFile.setEditable(true); fileOutputFileChangeDest.setDisable(false); getChoosedLabelOutputFileFolder.setDisable(false); choosedLabel = changeLabel; choosedLabelType = "ENDECRYPT"; } else { enDecryptInputOutputFiles.keySet().forEach(label -> label.setStyle(null)); fileDecryptOutputFile.setEditable(false); fileEncryptOutputFile.setEditable(false); fileOutputFileChangeDest.setDisable(true); getChoosedLabelOutputFileFolder.setDisable(true); } } /** *

Opens a file chooser GUI where the user can select the files that should be en- / decrypted. * Get called if the 'Choose files...' in the file en- / decrypt section button is pressed

* * @since 1.12.0 */ public void fileEnDecryptChooseFiles() { FileChooser fileChooser = new FileChooser(); fileChooser.setTitle("Choose files"); fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("All files", "*.*")); List files = fileChooser.showOpenMultipleDialog(rootWindow.getScene().getWindow()); try { if (files.size() > 0) { files.forEach(this::fileEnDecryptAddFile); } } catch (NullPointerException e) { e.printStackTrace(); } } /** *

Opens a directory chooser GUI where the user can select the directories that should be en- / decrypted. * Get called if the 'directories...' in the file en- / decrypt section button is pressed

* * @since 1.12.0 */ public void fileEnDecryptChooseDirectories() { DirectoryChooser directoryChooser = new DirectoryChooser(); directoryChooser.setTitle("Choose directories"); File file = directoryChooser.showDialog(rootWindow.getScene().getWindow()); try { fileEnDecryptAddFile(file); } catch (NullPointerException e) { e.printStackTrace(); } } /** *

Get called if user drags a (normal or internet) file over the en- / decrypt file box

* * @param event source * * @since 1.2.0 */ public void onFileEnDecryptDragOver(DragEvent event) { Dragboard dragboard = event.getDragboard(); if (event.getGestureSource() != fileEnDecryptInputFiles) { if (dragboard.hasFiles()) { event.acceptTransferModes(TransferMode.COPY_OR_MOVE); } else if (dragboard.hasUrl()) { String url = dragboard.getUrl(); String urlFilename = dragboard.getUrl().split("/")[dragboard.getUrl().split("/").length - 1]; if (url.startsWith("data:")) { try { final int dataStartIndex = url.indexOf(",") + 1; final String data = url.substring(dataStartIndex); java.util.Base64.getDecoder().decode(data); event.acceptTransferModes(TransferMode.COPY_OR_MOVE); } catch (Exception e) { e.printStackTrace(); } } else if (urlFilename.contains(".") && Utils.hasAnyCharacter("\\/:*?|<>\"", urlFilename)) { try { new URL(url); event.acceptTransferModes(TransferMode.COPY_OR_MOVE); } catch (Exception e) { e.printStackTrace(); return; } } else { event.acceptTransferModes(TransferMode.COPY_OR_MOVE); } } } } /** *

Get called if the user drops the dragged (normal or internet) file over the en- / decrypt file box

* * @param event source * @throws URISyntaxException * * @since 1.2.0 */ public void onFileEnDecryptDragNDrop(DragEvent event) throws URISyntaxException { Dragboard dragboard = event.getDragboard(); if (dragboard.hasFiles()) { dragboard.getFiles().forEach(this::fileEnDecryptAddFile); } else if (dragboard.hasUrl()) { String url = dragboard.getUrl(); String urlFilename = dragboard.getUrl().split("/")[dragboard.getUrl().split("/").length - 1]; if (url.startsWith("data:")) { fileEnDecryptAddInternetFile(url, DATAFILEURL); } else if (urlFilename.contains(".") && Utils.hasAnyCharacter("\\/:*?|<>\"", urlFilename)) { fileEnDecryptAddInternetFile(url, FILEFILEURL); } else { fileEnDecryptAddInternetFile(url, NONSPECIFICFILEURL); } } } /** *

If the user presses Ctrl + V: Adds the last object in clipboard (if file) for en- / decryption. * Get called if the user presses a key while selected file en- / decryption box

* * @param event source * @throws URISyntaxException * * @since 1.7.0 */ public void onFileEnDecryptPaste(KeyEvent event) throws URISyntaxException { if (paste.match(event)) { Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); Transferable transferable = clipboard.getContents(null); try { if (transferable != null) { if (transferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { Object objectFileList = transferable.getTransferData(DataFlavor.javaFileListFlavor); List files = (List) objectFileList; files.forEach(o -> fileEnDecryptAddFile((File) o)); } else if (transferable.isDataFlavorSupported(DataFlavor.imageFlavor)) { Object objectImage = transferable.getTransferData(DataFlavor.imageFlavor); fileEnDecryptAddClipboardImage((BufferedImage) objectImage); } } } catch (UnsupportedFlavorException | IOException e) { e.printStackTrace(); } } } /** *

Encrypt all files given files. * Get called if file 'Encrypt' button is pressed

* * @since 1.0.0 */ public void fileEncryptButton() { final byte[] salt; if (!fileEnDecryptSaltEntry.getText().isEmpty()) { salt = fileEnDecryptSaltEntry.getText().getBytes(StandardCharsets.UTF_8); } else { salt = new byte[16]; } if (!enDecryptInputOutputFiles.isEmpty()) { removeFileFromFileBox.setDisable(true); limitNumberOfThreads.setDisable(true); for(Map.Entry> entry: enDecryptInputOutputFiles.entrySet()) { Thread thread = new Thread(() -> { addFileEnDecryptThread(Thread.currentThread()); if (limitNumberOfThreads.isSelected()) { while (totalThreads.get() >= Runtime.getRuntime().availableProcessors()) { try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().stop(); } } } totalThreads.getAndIncrement(); Label inputFileLabel = entry.getKey(); ArrayList outputFileList = entry.getValue(); String fileEnDecryptAlgorithm = fileEnDecryptAlgorithmBox.getSelectionModel().getSelectedItem(); EnDecrypt.AES fileEncrypt = new EnDecrypt.AES(fileEnDecryptKeyEntry.getText(), salt, Integer.parseInt(fileEnDecryptAlgorithm.substring(fileEnDecryptAlgorithm.indexOf('-') + 1))); if (enDecryptInputOutputInternetFiles.containsKey(inputFileLabel)) { ArrayList fileSpecs = enDecryptInputOutputInternetFiles.get(inputFileLabel); int urlType = (int) fileSpecs.get(0); String url = (String) fileSpecs.get(1); try { if (urlType == FILEFILEURL || urlType == NONSPECIFICFILEURL) { URLConnection openURL = new URL(url).openConnection(); openURL.addRequestProperty("User-Agent", "Mozilla/5.0"); fileEncrypt.encryptFile(openURL.getInputStream(), new FileOutputStream((File) fileSpecs.get(2)), buffer); } else if (urlType == DATAFILEURL) { final int dataStartIndex = url.indexOf(",") + 1; final String data = url.substring(dataStartIndex); byte[] decoded = java.util.Base64.getDecoder().decode(data); fileEncrypt.encryptFile(new ByteArrayInputStream(decoded), new FileOutputStream((File) fileSpecs.get(2)), buffer); } } catch (FileNotFoundException | InvalidKeySpecException | NoSuchAlgorithmException | MalformedURLException | InvalidKeyException | NoSuchPaddingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); Platform.runLater(() -> errorAlert("IO Exception occurred", e.getMessage())); } } else if (enDecryptInputOutputClipboardImages.containsKey(inputFileLabel)) { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); BufferedImage bufferedImage = enDecryptInputOutputClipboardImages.get(inputFileLabel); try { ImageIO.write(bufferedImage, "png", byteArrayOutputStream); fileEncrypt.encryptFile(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()), new FileOutputStream(outputFileList.get(0).getAbsoluteFile()), buffer); } catch (IOException e) { e.printStackTrace(); Platform.runLater(() -> errorAlert("IO Exception occurred", e.getMessage())); } catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | InvalidKeySpecException e) { e.printStackTrace(); } } else { try { File inputFile = new File(inputFileLabel.getText()); if (inputFile.isFile()) { fileEncrypt.encryptFile(new FileInputStream(inputFile), new FileOutputStream(outputFileList.get(0)), buffer); } else { fileEncrypt.encryptDirectory(inputFileLabel.getText(), outputFileList.get(0).getAbsolutePath(), ".cryptoGX", buffer); if (!outputFileList.get(0).isDirectory()) { Platform.runLater(() -> warningAlert("Couldn't create directory\n '" + outputFileList.get(0).getAbsolutePath() + "'.\nTry again or restart cryptoGX with admin privileges")); } } } catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException | InvalidKeySpecException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); Platform.runLater(() -> errorAlert("IO Exception occurred", e.getMessage())); } } if (removeFileFromFileBox.isSelected()) { Platform.runLater(() -> fileEnDecryptDeleteEntry(entry.getKey())); } if ((getFileEnDecryptThreadsSize() - 1) <= 0) { fileEnDecryptLoading = false; Platform.runLater(() -> { fileEnDecryptLoadingImage.setImage(null); removeFileFromFileBox.setDisable(false); limitNumberOfThreads.setDisable(false); }); } removeFileEnDecryptThread(Thread.currentThread()); totalThreads.getAndDecrement(); }); thread.setDaemon(false); thread.start(); if (!fileEnDecryptLoading) { fileEnDecryptLoadingImage.setImage(loadingImage); } fileEnDecryptLoading = true; } } } /** *

Decrypt all files given files. * Get called if file 'Decrypt' button is pressed

* * @since 1.0.0 */ public void fileDecryptButton() { final byte[] salt; if (!fileEnDecryptSaltEntry.getText().isEmpty()) { salt = fileEnDecryptSaltEntry.getText().getBytes(StandardCharsets.UTF_8); } else { salt = new byte[16]; } if (!enDecryptInputOutputFiles.isEmpty()) { removeFileFromFileBox.setDisable(true); limitNumberOfThreads.setDisable(true); for(Map.Entry> entry: enDecryptInputOutputFiles.entrySet()) { Thread thread = new Thread(() -> { addFileEnDecryptThread(Thread.currentThread()); if (limitNumberOfThreads.isSelected()) { while (totalThreads.get() >= Runtime.getRuntime().availableProcessors()) { try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().stop(); } } } totalThreads.getAndIncrement(); Label inputFileLabel = entry.getKey(); ArrayList outputFileList = entry.getValue(); String fileEnDecryptAlgorithm = fileEnDecryptAlgorithmBox.getSelectionModel().getSelectedItem(); EnDecrypt.AES fileDecrypt = new EnDecrypt.AES(fileEnDecryptKeyEntry.getText(), salt, Integer.parseInt(fileEnDecryptAlgorithm.substring(fileEnDecryptAlgorithm.indexOf('-') + 1))); if (enDecryptInputOutputInternetFiles.containsKey(entry.getKey())) { ArrayList imageSpecs = enDecryptInputOutputInternetFiles.get(entry.getKey()); int urlType = (int) imageSpecs.get(0); String url = (String) imageSpecs.get(1); try { if (urlType == FILEFILEURL) { URLConnection openURL = new URL(url).openConnection(); openURL.addRequestProperty("User-Agent", "Mozilla/5.0"); fileDecrypt.decryptFile(openURL.getInputStream(), new FileOutputStream((File) imageSpecs.get(2)), buffer); fileDecrypt.decryptFile(openURL.getInputStream(), new FileOutputStream((File) imageSpecs.get(2)), buffer); } else if (urlType == DATAFILEURL) { final int dataStartIndex = url.indexOf(",") + 1; final String data = url.substring(dataStartIndex); byte[] decoded = java.util.Base64.getDecoder().decode(data); fileDecrypt.decryptFile(new ByteArrayInputStream(decoded), new FileOutputStream((File) imageSpecs.get(2)), buffer); } else if (urlType == NONSPECIFICFILEURL) { URLConnection openURL = new URL(url).openConnection(); openURL.addRequestProperty("User-Agent", "Mozilla/5.0"); fileDecrypt.decryptFile(openURL.getInputStream(), new FileOutputStream((File) imageSpecs.get(2)), buffer); } } catch (FileNotFoundException | InvalidKeySpecException | NoSuchAlgorithmException | MalformedURLException | InvalidKeyException | NoSuchPaddingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); Platform.runLater(() -> errorAlert("IO Exception occurred", e.getMessage())); } } else if (enDecryptInputOutputClipboardImages.containsKey(inputFileLabel)) { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); BufferedImage bufferedImage = enDecryptInputOutputClipboardImages.get(inputFileLabel); try { ImageIO.write(bufferedImage, "png", byteArrayOutputStream); fileDecrypt.decryptFile(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()), new FileOutputStream(outputFileList.get(1).getAbsolutePath()), buffer); } catch (IOException e) { e.printStackTrace(); Platform.runLater(() -> errorAlert("IO Exception occurred", e.getMessage())); } catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | InvalidKeySpecException e) { e.printStackTrace(); } } else { try { File inputFile = new File(inputFileLabel.getText()); if (inputFile.isFile()) { fileDecrypt.decryptFile(new FileInputStream(inputFile), new FileOutputStream(outputFileList.get(1)), buffer); } else { fileDecrypt.decryptDirectory(inputFileLabel.getText(), outputFileList.get(1).getAbsolutePath(), "@.cryptoGX@", buffer); if (!outputFileList.get(1).isDirectory()) { Platform.runLater(() -> warningAlert("Couldn't create directory\n '" + outputFileList.get(1).getAbsolutePath() + "'.\nTry again or restart cryptoGX with admin privileges")); } } } catch (NoSuchPaddingException | InvalidKeySpecException | InvalidKeyException | NoSuchAlgorithmException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); Platform.runLater(() -> errorAlert("IO Exception occurred", e.getMessage())); } catch (IllegalArgumentException e) { e.printStackTrace(); Platform.runLater(() -> errorAlert("Wrong text for encryption is given", e.getMessage())); } } if (removeFileFromFileBox.isSelected()) { Platform.runLater(() -> fileEnDecryptDeleteEntry(entry.getKey())); } if ((getFileEnDecryptThreadsSize() - 1) <= 0) { fileEnDecryptLoading = false; Platform.runLater(() -> { fileEnDecryptLoadingImage.setImage(null); removeFileFromFileBox.setDisable(false); limitNumberOfThreads.setDisable(false); }); } removeFileEnDecryptThread(Thread.currentThread()); totalThreads.getAndDecrement(); }); thread.setDaemon(false); thread.start(); if (!fileEnDecryptLoading) { fileEnDecryptLoadingImage.setImage(loadingImage); } fileEnDecryptLoading = true; } } } /** *

Cancels the file en- / decryption. * Get called if the file en- / decrypt 'Cancel' button is pressed

* * @since 1.12.0 */ public void fileEnDecryptCancelButton() { for (Iterator iterator = getFileEnDecryptThreads().iterator(); iterator.hasNext();) { Thread thread = iterator.next(); while (thread.isAlive() && !thread.isInterrupted()) { thread.stop(); thread.interrupt(); } iterator.remove(); } fileEnDecryptLoading = false; fileEnDecryptLoadingImage.setImage(null); removeFileFromFileBox.setDisable(false); limitNumberOfThreads.setDisable(false); } //-----fileDelete-----// /** *

Synchronized method to get the list of threads which delete files

* * @return list of threads which delete files * * @since 1.2.0 */ private synchronized List getFileDeleteThreads() { return fileDeleteThreads; } /** *

Synchronized method to get the number of threads which delete files

* * @return number of threads which delete files * * @since 1.2.0 */ private synchronized int getFileDeleteThreadsSize() { return fileDeleteThreads.size(); } /** *

Synchronized method to add a thread to the file delete list of current running file delete threads

* * @param thread that should be added * * @since 1.2.0 */ private synchronized void addFileDeleteThread(Thread thread) { fileDeleteThreads.add(thread); } /** *

Synchronized method to remove a thread from the file delete list of current file delete threads

* * @param thread that should be removed * * @since 1.2.0 */ private synchronized void removeFileDeleteThread(Thread thread) { fileDeleteThreads.remove(thread); } /** *

Adds a file that should be deleted

* * @param file that should be added * * @since 1.2.0 */ private void fileDeleteAddFile(File file) { for (File f: deleteInputFiles.values()) { if (f.getAbsolutePath().equals(file.getAbsolutePath())) { return; } } Label newLabel = new Label(file.getAbsolutePath()); newLabel.setOnKeyTyped(this::keyTypedTooltip); newLabel.setOnMouseMoved(this::mouseOverEntryTooltip); newLabel.setOnMouseExited(event -> mouseExitEntryTooltip()); newLabel.setOnMouseClicked(event -> fileDeleteSelected(newLabel)); newLabel.setContextMenu(fileDeleteInputContextMenu); fileDeleteInputFiles.getChildren().add(newLabel); deleteInputFiles.put(newLabel, file.getAbsoluteFile()); } /** *

Changes the highlight of the clicked item in the file delete box. * Get called if the user click an non-highlighted item in the file delete box

* * @param changeLabel is the label that the user has clicked * * @since 1.2.0 */ private void fileDeleteSelected(Label changeLabel) { if (changeLabel != null) { fileEnDecryptSelected(null); deleteInputFiles.keySet().forEach(label -> label.setStyle(null)); changeLabel.setStyle("-fx-background-color: lightblue; -fx-border-color: #292929"); choosedLabel = changeLabel; choosedLabelType = "DELETE"; } else { deleteInputFiles.keySet().forEach(label -> label.setStyle(null)); } } /** *

Deletes an entry for file delete. * Get called if the user presses 'del' or delete the entry in the file delete box via the right click tooltip

* * @param label that should be deleted * * @since 1.12.0 */ private void fileDeleteDeleteEntry(Label label) { deleteInputFiles.remove(choosedLabel); if (fileDeleteInputFiles.getChildren().size() - 1 >= 1) { for (int i=0; iOpens a file chooser GUI where the user can select the files that should be en- / decrypted. * Get called if the 'Choose files...' in the delete section button is pressed

* * @since 1.12.0 */ public void fileDeleteChooseFiles() { FileChooser fileChooser = new FileChooser(); fileChooser.setTitle("Choose files"); fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("All Files", "*.*")); List files = fileChooser.showOpenMultipleDialog(rootWindow.getScene().getWindow()); try { if (files.size() > 0) { files.forEach(this::fileDeleteAddFile); } } catch (NullPointerException e) { e.printStackTrace(); } } /** *

Opens a directory chooser GUI where the user can select the directories that should be en- / decrypted. * Get called if the 'Choose directories...' in the delete section button is pressed

* * @since 1.12.0 */ public void fileDeleteChooseDirectories() { DirectoryChooser directoryChooser = new DirectoryChooser(); directoryChooser.setTitle("Choose directories"); File file = directoryChooser.showDialog(rootWindow.getScene().getWindow()); try { fileDeleteAddFile(file); } catch (NullPointerException e) { e.printStackTrace(); } } /** *

Get called if user drags a file over the delete file box

* * @param event source * * @since 1.2.0 */ public void onFileDeleteDragOver(DragEvent event) { Dragboard dragboard = event.getDragboard(); if (event.getGestureSource() != fileDeleteInputFiles && dragboard.hasFiles()) { event.acceptTransferModes(TransferMode.COPY_OR_MOVE); } } /** *

Get called if the user drops the dragged file over the delete file box

* * @param event source * * @since 1.2.0 */ public void onFileDeleteDragNDrop(DragEvent event) { Dragboard dragboard = event.getDragboard(); if (dragboard.hasFiles()) { dragboard.getFiles().forEach(file -> { if (file.isFile() || file.isDirectory()) { fileDeleteAddFile(file); } }); } } /** *

Delete all given files. * Get called if 'Delete' button is pressed

* * @since 1.2.0 */ public void fileDelete() { if (!fileDeleteLoading && !deleteInputFiles.isEmpty()) { fileDeleteLoadingImage.setImage(loadingImage); } int deleteIterations = Integer.parseInt(fileDeleteIterationsEntry.getText()); for (Map.Entry map : deleteInputFiles.entrySet()) { Label label = map.getKey(); File file = map.getValue(); Thread thread = new Thread(() -> { addFileDeleteThread(Thread.currentThread()); if (limitNumberOfThreads.isSelected()) { while (totalThreads.get() >= Runtime.getRuntime().availableProcessors()) { try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().stop(); } } } totalThreads.getAndIncrement(); try { if (file.isFile()) { SecureDelete.deleteFile(file, deleteIterations, buffer); } else if (file.isDirectory()) { SecureDelete.deleteDirectory(file.getAbsolutePath(), deleteIterations, buffer); } } catch (IOException e) { e.printStackTrace(); } if ((getFileDeleteThreadsSize() - 1) <= 0) { fileDeleteLoading = false; Platform.runLater(() -> fileDeleteLoadingImage.setImage(null)); } if (label == choosedLabel) { choosedLabel = null; choosedLabelType = null; } Platform.runLater(() -> fileDeleteInputFiles.getChildren().remove(label)); removeFileDeleteThread(Thread.currentThread()); totalThreads.getAndDecrement(); }); thread.setDaemon(false); thread.start(); fileDeleteLoading = true; } } /** *

Cancels the file en- / decryption. * Get called if the file delete 'Cancel' button is pressed

* * @since 1.12.0 */ public void fileDeleteCancelButton() { for (Iterator iterator = getFileDeleteThreads().iterator(); iterator.hasNext();) { Thread thread = iterator.next(); while (thread.isAlive() & !thread.isInterrupted()) { thread.stop(); thread.interrupt(); } iterator.remove(); } fileDeleteLoading = false; fileDeleteLoadingImage.setImage(null); } /** * Called to initialize a controller after its root element has been * completely processed. * * @param location * The location used to resolve relative paths for the root object, or * null if the location is not known. * * @param resources * The resources used to localize the root object, or null if * the root object was not localized. * * @since 1.0.0 */ @Override public void initialize(URL location, ResourceBundle resources) { //-----general-----// currentConfigSettings.put("textKey", configDefaultTextKey); currentConfigSettings.put("textSalt", configDefaultTextSalt); currentConfigSettings.put("textAlgorithm", configDefaultTextAlgorithm); currentConfigSettings.put("fileEnDecryptKey", configDefaultFileEnDecryptKey); currentConfigSettings.put("fileEnDecryptSalt", configDefaultFileEnDecryptSalt); currentConfigSettings.put("fileEnDecryptAlgorithm", configDefaultFileEnDecryptAlgorithm); currentConfigSettings.put("fileDeleteIterations", String.valueOf(configDefaultFileDeleteIterations)); currentConfigSettings.put("fileOutputPath", configDefaultFileOutputPath); currentConfigSettings.put("removeFromFileBox", String.valueOf(configDefaultRemoveFileFromFileBox)); currentConfigSettings.put("limitNumberOfThreads", String.valueOf(configDefaultLimitNumberOfThreads)); menubar.setOnMouseDragged(event -> { Stage stage = (Stage) ((Node) event.getSource()).getScene().getWindow(); stage.setX(event.getScreenX() + menubarX); stage.setY(event.getScreenY() + menubarY); }); menubar.setOnMousePressed(event -> { Scene scene = ((Node) event.getSource()).getScene(); menubarX = scene.getX() - event.getSceneX(); menubarY = scene.getY() - event.getSceneY(); }); rootWindow.setOnKeyReleased(event -> { if (event.getCode() == KeyCode.DELETE && choosedLabelType != null) { if (choosedLabelType.equals("ENDECRYPT")) { fileEnDecryptDeleteEntry(choosedLabel); } else if (choosedLabelType.equals("DELETE")) { fileDeleteDeleteEntry(choosedLabel); } } }); getChoosedLabelInputFileFolder.setOnAction(event -> { Desktop desktop = Desktop.getDesktop(); String filePath = choosedLabel.getText(); try { desktop.open(new File(filePath.substring(0, filePath.lastIndexOf(System.getProperty("file.separator"))))); } catch (IOException e) { errorAlert("An unexpected IO Exception occurred", e.getMessage()); } }); getChoosedLabelOutputFileFolder.setOnAction(event -> { Desktop desktop; String filePath; if (enDecryptInputOutputFiles.containsKey(choosedLabel)) { desktop = Desktop.getDesktop(); filePath = enDecryptInputOutputFiles.get(choosedLabel).get(0).getAbsolutePath(); } else { return; } try { desktop.open(new File(filePath.substring(0, filePath.lastIndexOf(System.getProperty("file.separator"))))); } catch (IOException e) { errorAlert("An unexpected IO Exception occurred", e.getMessage()); } }); setDefaultOutputPath.setOnAction(event -> { DirectoryChooser directoryChooser = new DirectoryChooser(); File directory = directoryChooser.showDialog(rootWindow.getScene().getWindow()); try { currentConfigSettings.replace("fileOutputPath", directory.getAbsolutePath()); } catch (NullPointerException e) { e.printStackTrace(); } }); settingsMenu.setOnShowing(event -> { loadSettings.setDisable(!isConfig); exportSettings.setDisable(!isConfig); }); removeFileFromFileBox.setOnAction(event -> currentConfigSettings.replace("removeFromFileBox", String.valueOf(removeFileFromFileBox.isSelected()))); limitNumberOfThreads.setOnAction(event -> currentConfigSettings.replace("limitNumberOfThreads", String.valueOf(limitNumberOfThreads.isSelected()))); saveSettings.setOnAction(event -> { try { addSettingGUI(rootWindow.getScene().getWindow(), currentConfigSettings); if (config.isFile()) { isConfig = true; } } catch (IOException e) { e.printStackTrace(); } }); loadSettings.setOnAction(event -> { try { currentConfigSettings = (HashMap) loadSettingsGUI(rootWindow.getScene().getWindow()).values().toArray()[0]; textKeyEntry.setText(currentConfigSettings.get("textKey")); textSaltEntry.setText(currentConfigSettings.get("textSalt")); textAlgorithmBox.setValue(currentConfigSettings.get("textAlgorithm")); fileEnDecryptKeyEntry.setText(currentConfigSettings.get("fileEnDecryptKey")); fileEnDecryptSaltEntry.setText(currentConfigSettings.get("fileEnDecryptSalt")); fileEnDecryptAlgorithmBox.setValue(currentConfigSettings.get("fileEnDecryptAlgorithm")); fileDeleteIterationsEntry.setText(currentConfigSettings.get("fileDeleteIterations")); removeFileFromFileBox.setSelected(Boolean.parseBoolean(currentConfigSettings.get("removeFromFileBox"))); limitNumberOfThreads.setSelected(Boolean.parseBoolean(currentConfigSettings.get("limitNumberOfThreads"))); } catch (IOException e) { e.printStackTrace(); } catch (ArrayIndexOutOfBoundsException ex) { try { SecureDelete.deleteFile(config, 5, buffer); isConfig = false; } catch (IOException e) { e.printStackTrace(); } } }); exportSettings.setOnAction(event -> { try { exportSettingsGUI(rootWindow.getScene().getWindow()); } catch (IOException e) { e.printStackTrace(); errorAlert("IO Exception occurred", e.getMessage()); } }); importSettings.setOnAction(event -> { FileChooser fileChooser = new FileChooser(); fileChooser.setTitle("Import settings"); fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("Config files", "*.config*", "*.xml"), new FileChooser.ExtensionFilter("All files", "*.*")); File file = fileChooser.showOpenDialog(rootWindow.getScene().getWindow()); if (file != null) { if (isConfig) { writeSettings(config, readSettings(file)); } else { writeSettings(config, readSettings(file)); isConfig = true; } } }); //-----text------// textAlgorithmBox.setItems(FXCollections.observableArrayList(Utils.algorithms.keySet())); textAlgorithmBox.setValue(Utils.algorithms.keySet().toArray(new String[Utils.algorithms.size()])[0]); //-----fileEnDecrypt-----// fileEnDecryptAlgorithmBox.setItems(FXCollections.observableArrayList(Utils.algorithms.keySet())); fileEnDecryptAlgorithmBox.setValue(Utils.algorithms.keySet().toArray(new String[Utils.algorithms.size()])[0]); MenuItem enDecryptRemove = new MenuItem(); enDecryptRemove.setText("Remove"); enDecryptRemove.setOnAction(removeEvent -> fileEnDecryptDeleteEntry(choosedLabel)); MenuItem enDecryptChangeDest = new MenuItem(); enDecryptChangeDest.setText("Change output file / directory"); enDecryptChangeDest.setOnAction(outputFileChangeEvent -> { File file; if (new File(choosedLabel.getText()).isFile()) { FileChooser destChooser = new FileChooser(); destChooser.setTitle("Choose or create new file"); destChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("All files", "*.*")); file = destChooser.showSaveDialog(rootWindow.getScene().getWindow()); } else { DirectoryChooser destChooser = new DirectoryChooser(); destChooser.setTitle("Choose or create new directory"); file = destChooser.showDialog(rootWindow.getScene().getWindow()); } if (file != null) { for (Map.Entry> entry : enDecryptInputOutputFiles.entrySet()) { if (entry.getKey().getText().equals(choosedLabel.getText())) { ArrayList changedFile = new ArrayList<>(); changedFile.add(0, file); changedFile.add(1, file); enDecryptInputOutputFiles.replace(entry.getKey(), entry.getValue(), changedFile); fileOutputFilesChangeText((Label) fileEnDecryptLabelEvent.getSource(), file.getAbsolutePath(), file.getAbsolutePath()); break; } } } }); fileEnDecryptInputContextMenu.getItems().addAll(enDecryptRemove, enDecryptChangeDest); ContextMenu fileEnDecryptInputFilesMenu = new ContextMenu(); MenuItem enDecryptPaste = new MenuItem(); enDecryptPaste.setText("Paste"); enDecryptPaste.setOnAction(pasteEvent -> { Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); Transferable transferable = clipboard.getContents(null); try { if (transferable != null) { if (transferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { Object objectFileList = transferable.getTransferData(DataFlavor.javaFileListFlavor); List files = (List) objectFileList; files.forEach(o -> fileEnDecryptAddFile((File) o)); } else if (transferable.isDataFlavorSupported(DataFlavor.imageFlavor)) { Object objectImage = transferable.getTransferData(DataFlavor.imageFlavor); fileEnDecryptAddClipboardImage((BufferedImage) objectImage); } } } catch (UnsupportedFlavorException | IOException | URISyntaxException e) { e.printStackTrace(); } }); fileEnDecryptInputFilesMenu.getItems().add(enDecryptPaste); fileEnDecryptInputFiles.setOnContextMenuRequested(event -> { if (!fileEnDecryptInputContextMenu.isShowing()) { fileEnDecryptInputFilesMenu.show(((VBox) event.getSource()).getParent().getScene().getWindow(), event.getScreenX(), event.getScreenY()); } }); fileOutputFileChangeDest.setOnAction(event -> { FileChooser fileDestChooser = new FileChooser(); fileDestChooser.setTitle("Choose or create new file"); fileDestChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("All files", "*.*")); File file = fileDestChooser.showSaveDialog(rootWindow.getScene().getWindow()); if (file != null) { for (Map.Entry> entry : enDecryptInputOutputFiles.entrySet()) { if (entry.getKey().getText().equals(choosedLabel.getText())) { ArrayList changedFile = new ArrayList<>(); changedFile.add(0, file); changedFile.add(1, file); enDecryptInputOutputFiles.replace(entry.getKey(), entry.getValue(), changedFile); fileOutputFilesChangeText((Label) fileEnDecryptLabelEvent.getSource(), file.getAbsolutePath(), file.getAbsolutePath()); break; } } } }); fileOutputFileChangeDest.setDisable(true); getChoosedLabelOutputFileFolder.setDisable(true); fileEncryptOutputFile.textProperty().addListener((observable, oldValue, newValue) -> fileOutputFilesChangeText(choosedLabel, newValue, fileDecryptOutputFile.getText())); fileDecryptOutputFile.textProperty().addListener((observable, oldValue, newValue) -> fileOutputFilesChangeText(choosedLabel, fileEncryptOutputFile.getText(), newValue)); //-----fileDelete-----// MenuItem deleteRemove = new MenuItem(); deleteRemove.setText("Remove"); deleteRemove.setOnAction(removeEvent -> fileDeleteDeleteEntry(choosedLabel)); fileDeleteInputContextMenu.getItems().add(deleteRemove); ContextMenu fileDeleteInputFilesMenu = new ContextMenu(); MenuItem deletePaste = new MenuItem(); deletePaste.setText("Paste"); deletePaste.setOnAction(pasteEvent -> { Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); Transferable transferable = clipboard.getContents(null); try { if (transferable != null && transferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { Object objectFileList = transferable.getTransferData(DataFlavor.javaFileListFlavor); List files = (List) objectFileList; files.forEach(o -> fileDeleteAddFile((File) o)); } } catch (UnsupportedFlavorException | IOException e) { e.printStackTrace(); } }); fileDeleteInputFilesMenu.getItems().add(deletePaste); fileDeleteInputFiles.setOnContextMenuRequested(event -> { if (!fileDeleteInputContextMenu.isShowing()) { fileDeleteInputFilesMenu.show(((VBox) event.getSource()).getParent().getScene().getWindow(), event.getScreenX(), event.getScreenY()); } }); fileDeleteIterationsEntry.textProperty().addListener((observable, oldValue, newValue) -> { if (!newValue.matches("[0-9]*")) { fileDeleteIterationsEntry.setText(oldValue); } }); Thread t = new Thread(() -> { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } if (isConfig) { Platform.runLater(() -> { try { currentConfigSettings = (HashMap) loadSettingsGUI(rootWindow.getScene().getWindow()).values().toArray()[0]; textKeyEntry.setText(currentConfigSettings.get("textKey")); textSaltEntry.setText(currentConfigSettings.get("textSalt")); textAlgorithmBox.setValue(currentConfigSettings.get("textAlgorithm")); fileEnDecryptKeyEntry.setText(currentConfigSettings.get("fileEnDecryptKey")); fileEnDecryptSaltEntry.setText(currentConfigSettings.get("fileEnDecryptSalt")); fileEnDecryptAlgorithmBox.setValue(currentConfigSettings.get("fileEnDecryptAlgorithm")); fileDeleteIterationsEntry.setText(currentConfigSettings.get("fileDeleteIterations")); removeFileFromFileBox.setSelected(Boolean.parseBoolean(currentConfigSettings.get("removeFromFileBox"))); limitNumberOfThreads.setSelected(Boolean.parseBoolean(currentConfigSettings.get("limitNumberOfThreads"))); } catch (IOException e) { e.printStackTrace(); } catch (ArrayIndexOutOfBoundsException ex) { try { SecureDelete.deleteFile(config, 5, buffer); isConfig = false; } catch (IOException e) { e.printStackTrace(); } } }); } }); t.start(); } }