diff --git a/src/main/java/nsusbloader/Controllers/FilesDropHandle.java b/src/main/java/nsusbloader/Controllers/FilesDropHandle.java
new file mode 100644
index 0000000..4fb9e96
--- /dev/null
+++ b/src/main/java/nsusbloader/Controllers/FilesDropHandle.java
@@ -0,0 +1,120 @@
+/*
+ Copyright 2019-2020 Dmitry Isaenko
+
+ This file is part of NS-USBloader.
+
+ NS-USBloader is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ NS-USBloader is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with NS-USBloader. If not, see .
+*/
+package nsusbloader.Controllers;
+
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.control.ProgressBar;
+import javafx.scene.control.ProgressIndicator;
+import javafx.scene.image.Image;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+import javafx.scene.layout.Priority;
+import javafx.scene.layout.VBox;
+import javafx.stage.Stage;
+import nsusbloader.AppPreferences;
+import nsusbloader.MediatorControl;
+
+import java.io.File;
+import java.util.List;
+import java.util.ResourceBundle;
+
+public class FilesDropHandle {
+
+ public FilesDropHandle(List files, String filesRegex, String foldersRegex){
+
+ //
+ // TODO: ADD GRAPHICS BEFORE RELEASE !
+ //
+
+ FilesDropHandleTask filesDropHandleTask = new FilesDropHandleTask(files, filesRegex, foldersRegex);
+
+ ResourceBundle resourceBundle = MediatorControl.getInstance().getResourceBundle();
+ Button cancelButton = new Button(resourceBundle.getString("btn_Cancel"));
+
+ ProgressIndicator progressIndicator = new ProgressIndicator();
+ progressIndicator.setProgress(ProgressIndicator.INDETERMINATE_PROGRESS);
+
+ Label downloadStatusLabel = new Label();
+ downloadStatusLabel.setWrapText(true);
+ downloadStatusLabel.textProperty().bind(filesDropHandleTask.messageProperty());
+
+ Pane fillerPane1 = new Pane();
+ Pane fillerPane2 = new Pane();
+
+ VBox parentVBox = new VBox();
+ parentVBox.setAlignment(Pos.TOP_CENTER);
+ parentVBox.setFillWidth(true);
+ parentVBox.setSpacing(5.0);
+ parentVBox.setPadding(new Insets(5.0));
+ parentVBox.setFillWidth(true);
+ parentVBox.getChildren().addAll(
+ downloadStatusLabel,
+ fillerPane1,
+ progressIndicator,
+ fillerPane2,
+ cancelButton
+ ); // TODO:FIX
+
+ VBox.setVgrow(fillerPane1, Priority.ALWAYS);
+ VBox.setVgrow(fillerPane2, Priority.ALWAYS);
+
+ Stage stage = new Stage();
+ stage.setTitle(resourceBundle.getString("windowTitleAddingFiles"));
+ stage.getIcons().addAll(
+ new Image("/res/dwnload_ico32x32.png"), //TODO: REDRAW
+ new Image("/res/dwnload_ico48x48.png"),
+ new Image("/res/dwnload_ico64x64.png"),
+ new Image("/res/dwnload_ico128x128.png")
+ );
+ stage.setMinWidth(300);
+ stage.setMinHeight(175);
+ stage.setAlwaysOnTop(true);
+ Scene mainScene = new Scene(parentVBox, 310, 185);
+
+ mainScene.getStylesheets().add(AppPreferences.getInstance().getTheme());
+
+ stage.setOnHidden(windowEvent -> filesDropHandleTask.cancel(true ) );
+
+ stage.setScene(mainScene);
+ stage.show();
+ stage.toFront();
+
+ filesDropHandleTask.setOnSucceeded(event -> {
+ cancelButton.setText(resourceBundle.getString("btn_Close"));
+
+ List allFiles = filesDropHandleTask.getValue();
+
+ if (! allFiles.isEmpty()) {
+ MediatorControl.getInstance().getGamesController().tableFilesListController.setFiles(allFiles);
+ }
+ stage.close();
+ });
+
+ new Thread(filesDropHandleTask).start();
+
+ cancelButton.setOnAction(actionEvent -> {
+ filesDropHandleTask.cancel(true);
+ stage.close();
+ });
+ }
+}
diff --git a/src/main/java/nsusbloader/Controllers/FilesDropHandleTask.java b/src/main/java/nsusbloader/Controllers/FilesDropHandleTask.java
new file mode 100644
index 0000000..93bc8ad
--- /dev/null
+++ b/src/main/java/nsusbloader/Controllers/FilesDropHandleTask.java
@@ -0,0 +1,96 @@
+/*
+ Copyright 2019-2020 Dmitry Isaenko
+
+ This file is part of NS-USBloader.
+
+ NS-USBloader is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ NS-USBloader is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with NS-USBloader. If not, see .
+*/
+package nsusbloader.Controllers;
+
+import javafx.concurrent.Task;
+import nsusbloader.MediatorControl;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+public class FilesDropHandleTask extends Task> {
+ private final String filesRegex;
+ private final String foldersRegex;
+
+ private final List filesDropped;
+ private final List allFiles;
+
+ private String messageTemplate;
+ private long filesScanned = 0;
+ private long filesAdded = 0;
+
+ FilesDropHandleTask(List files,
+ String filesRegex,
+ String foldersRegex) {
+ this.filesDropped = files;
+ this.filesRegex = filesRegex;
+ this.foldersRegex = foldersRegex;
+ this.allFiles = new ArrayList<>();
+ this.messageTemplate = MediatorControl.getInstance().getResourceBundle().getString("windowBodyFilesScanned");
+ }
+
+ @Override
+ protected List call() {
+ if (filesDropped == null || filesDropped.size() == 0)
+ return allFiles;
+
+ for (File file : filesDropped){
+ if (isCancelled())
+ return new ArrayList<>();
+ collectFiles(file);
+ updateMessage(String.format(messageTemplate, filesScanned++, filesAdded));
+ }
+
+ return allFiles;
+ }
+
+ private void collectFiles(File startFolder) {
+ if (startFolder == null)
+ return;
+
+ final String startFolderNameInLowercase = startFolder.getName().toLowerCase();
+
+ if (startFolder.isFile()) {
+ if (startFolderNameInLowercase.matches(filesRegex)) {
+ allFiles.add(startFolder);
+ filesAdded++;
+ }
+ return;
+ }
+
+ if (startFolderNameInLowercase.matches(foldersRegex)) {
+ allFiles.add(startFolder);
+ filesAdded++;
+ return;
+ }
+
+ File[] files = startFolder.listFiles();
+ if (files == null)
+ return;
+
+ for (File file : files) {
+ if (isCancelled())
+ return;
+ collectFiles(file);
+ updateMessage(String.format(messageTemplate, filesScanned++, filesAdded));
+ }
+ }
+
+}
diff --git a/src/main/java/nsusbloader/Controllers/GamesController.java b/src/main/java/nsusbloader/Controllers/GamesController.java
index d204c82..3ccccd9 100644
--- a/src/main/java/nsusbloader/Controllers/GamesController.java
+++ b/src/main/java/nsusbloader/Controllers/GamesController.java
@@ -41,10 +41,7 @@ import nsusbloader.ServiceWindow;
import java.io.File;
import java.net.URL;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ResourceBundle;
+import java.util.*;
import java.util.function.Consumer;
import java.util.function.Supplier;
@@ -294,6 +291,7 @@ public class GamesController implements Initializable {
* @param filesRegex for filenames
*/
// TODO: Too sophisticated. Should be moved to simple class to keep things simplier
+
private void collectFiles(List storage,
File startFolder,
final String filesRegex,
@@ -437,24 +435,10 @@ public class GamesController implements Initializable {
* */
@FXML
private void handleDrop(DragEvent event) {
- final String regexForFiles = getRegexForFiles();
- final String regexForFolders = getRegexForFolders();
-
List files = event.getDragboard().getFiles();
-
- performInBackgroundAndUpdate(() -> {
- List allFiles = new ArrayList<>();
- if (files != null && files.size() != 0) {
- files.forEach(f -> collectFiles(allFiles, f, regexForFiles, regexForFolders));
- }
- return allFiles;
- }, allFiles -> {
- if (!allFiles.isEmpty())
- tableFilesListController.setFiles(allFiles);
-
- event.setDropCompleted(true);
- event.consume();
- });
+ new FilesDropHandle(files, getRegexForFiles(), getRegexForFolders());
+ event.setDropCompleted(true);
+ event.consume();
}
/**
@@ -527,7 +511,6 @@ public class GamesController implements Initializable {
selectSplitNspBtn.setVisible(true);
}
selectNspBtn.setGraphic(btnSelectImage);
- //selectFolderBtn.setTooltip(new Tooltip(resourceBundle.getString("btn_OpenFolders_tooltip")));
}
/**
* Get 'Recent' path
diff --git a/src/main/java/nsusbloader/Controllers/NSTableViewController.java b/src/main/java/nsusbloader/Controllers/NSTableViewController.java
index 5017829..267da43 100644
--- a/src/main/java/nsusbloader/Controllers/NSTableViewController.java
+++ b/src/main/java/nsusbloader/Controllers/NSTableViewController.java
@@ -231,7 +231,7 @@ public class NSTableViewController implements Initializable {
/**
* Add files when user selected them
* */
- public void setFiles(List newFiles){
+ public synchronized void setFiles(List newFiles){
if (!rowsObsLst.isEmpty()){
List filesAlreayInList = new ArrayList<>();
for (NSLRowModel model : rowsObsLst)
diff --git a/src/main/java/nsusbloader/com/usb/TinFoil.java b/src/main/java/nsusbloader/com/usb/TinFoil.java
index 9ceba47..d033f08 100644
--- a/src/main/java/nsusbloader/com/usb/TinFoil.java
+++ b/src/main/java/nsusbloader/com/usb/TinFoil.java
@@ -222,7 +222,6 @@ class TinFoil extends TransferModule {
if ((currentOffset + chunk) >= size )
chunk = Math.toIntExact(size - currentOffset);
//System.out.println("CO: "+currentOffset+"\t\tEO: "+size+"\t\tRP: "+chunk); // NOTE: DEBUG
- logPrinter.updateProgress((currentOffset + chunk) / (size / 100.0) / 100.0);
readBuffer = new byte[chunk]; // TODO: not perfect moment, consider refactoring.
@@ -232,6 +231,7 @@ class TinFoil extends TransferModule {
if (writeUsb(readBuffer))
throw new IOException("TF Failure during file transfer.");
currentOffset += chunk;
+ logPrinter.updateProgress((double)currentOffset / (double)size);
}
nsSplitReader.close();
logPrinter.updateProgress(1.0);
@@ -251,7 +251,6 @@ class TinFoil extends TransferModule {
if ((currentOffset + chunk) >= size)
chunk = Math.toIntExact(size - currentOffset);
//System.out.println("CO: "+currentOffset+"\t\tEO: "+receivedRangeSize+"\t\tRP: "+chunk); // NOTE: DEBUG
- logPrinter.updateProgress((currentOffset + chunk) / (size / 100.0) / 100.0);
readBuffer = new byte[chunk];
@@ -261,6 +260,7 @@ class TinFoil extends TransferModule {
if (writeUsb(readBuffer))
throw new IOException("TF Failure during file transfer.");
currentOffset += chunk;
+ logPrinter.updateProgress((double)currentOffset / (double)size);
}
bufferedInStream.close();
logPrinter.updateProgress(1.0);
diff --git a/src/main/resources/locale.properties b/src/main/resources/locale.properties
index 7e9c763..b629b93 100644
--- a/src/main/resources/locale.properties
+++ b/src/main/resources/locale.properties
@@ -72,4 +72,6 @@ tab2_Cb_GlVersion=GoldLeaf version
tab2_Cb_GLshowNspOnly=Show only *.nsp in GoldLeaf.
windowBodyPleaseStopOtherProcessFirst=Please stop other active process before continuing.
tab2_Cb_foldersSelectorForRoms=Select folder with ROM files instead of selecting ROMs individually.
-tab2_Cb_foldersSelectorForRomsDesc=Changes 'Select files' button behaviour on 'Games' tab: instead of selecting ROM files one-by-one you can choose folder to add every supported file at once.
\ No newline at end of file
+tab2_Cb_foldersSelectorForRomsDesc=Changes 'Select files' button behaviour on 'Games' tab: instead of selecting ROM files one-by-one you can choose folder to add every supported file at once.
+windowTitleAddingFiles=Searching for files...
+windowBodyFilesScanned=Files scanned: %d\nWould be added: %d
\ No newline at end of file
diff --git a/src/main/resources/locale_en_US.properties b/src/main/resources/locale_en_US.properties
index 7e9c763..b629b93 100644
--- a/src/main/resources/locale_en_US.properties
+++ b/src/main/resources/locale_en_US.properties
@@ -72,4 +72,6 @@ tab2_Cb_GlVersion=GoldLeaf version
tab2_Cb_GLshowNspOnly=Show only *.nsp in GoldLeaf.
windowBodyPleaseStopOtherProcessFirst=Please stop other active process before continuing.
tab2_Cb_foldersSelectorForRoms=Select folder with ROM files instead of selecting ROMs individually.
-tab2_Cb_foldersSelectorForRomsDesc=Changes 'Select files' button behaviour on 'Games' tab: instead of selecting ROM files one-by-one you can choose folder to add every supported file at once.
\ No newline at end of file
+tab2_Cb_foldersSelectorForRomsDesc=Changes 'Select files' button behaviour on 'Games' tab: instead of selecting ROM files one-by-one you can choose folder to add every supported file at once.
+windowTitleAddingFiles=Searching for files...
+windowBodyFilesScanned=Files scanned: %d\nWould be added: %d
\ No newline at end of file
diff --git a/src/main/resources/locale_ru_RU.properties b/src/main/resources/locale_ru_RU.properties
index c8d6bc5..1dc4885 100644
--- a/src/main/resources/locale_ru_RU.properties
+++ b/src/main/resources/locale_ru_RU.properties
@@ -71,4 +71,6 @@ tab2_Cb_GlVersion=\u0412\u0435\u0440\u0441\u0438\u044F GoldLeaf
windowBodyPleaseStopOtherProcessFirst=\u041F\u043E\u0436\u0430\u043B\u0443\u0439\u0441\u0442\u0430, \u043E\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u0435 \u0434\u0440\u0443\u0433\u043E\u0439 \u0430\u043A\u0442\u0438\u0432\u043D\u044B\u0439 \u043F\u0440\u043E\u0446\u0435\u0441\u0441 \u043F\u0435\u0440\u0435\u0434 \u0442\u0435\u043C, \u043A\u0430\u043A \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0438\u0442\u044C.
tab2_Cb_foldersSelectorForRomsDesc=\u041C\u0435\u043D\u044F\u0435\u0442 \u043F\u043E\u0432\u0435\u0434\u0435\u043D\u0438\u0435 \u043A\u043D\u043E\u043F\u043A\u0438 "\u0412\u044B\u0431\u0440\u0430\u0442\u044C \u0444\u0430\u0439\u043B\u044B" \u043D\u0430 \u0432\u043A\u043B\u0430\u0434\u043A\u0435 '\u0418\u0433\u0440\u044B'. \u0412\u043C\u0435\u0441\u0442\u043E \u0432\u044B\u0431\u043E\u0440\u0430 ROM \u0444\u0430\u0439\u043B\u043E\u0432 \u043F\u043E \u043E\u0434\u043D\u043E\u043C\u0443 \u0432\u044B \u0443\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0442\u0435 \u043F\u0430\u043F\u043A\u0443, \u043F\u043E\u0441\u043B\u0435 \u0447\u0435\u0433\u043E \u0432\u0441\u0435 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043C\u044B\u0435 \u043E\u0431\u0440\u0430\u0437\u044B \u0434\u043E\u0431\u0430\u0432\u043B\u044F\u044E\u0442\u0441\u044F.
tab2_Cb_foldersSelectorForRoms=\u0412\u044B\u0431\u0438\u0440\u0430\u0442\u044C \u043F\u0430\u043F\u043A\u0443 \u0441 ROM \u0444\u0430\u0439\u043B\u0430\u043C\u0438 \u0432\u043C\u0435\u0441\u0442\u043E \u0432\u044B\u0431\u043E\u0440\u0430 \u0444\u0430\u0439\u043B\u043E\u0432 \u043F\u043E\u043E\u0434\u0438\u043D\u043E\u0447\u043A\u0435.
+windowTitleAddingFiles=\u0418\u0449\u0435\u043C \u0444\u0430\u0439\u043B\u044B...
+windowBodyFilesScanned=\u0424\u0430\u0439\u043B\u043E\u0432 \u043F\u0440\u043E\u0441\u043A\u0430\u043D\u0438\u0440\u043E\u0432\u0430\u043D\u043E: %d\n\u0418\u0437 \u043A\u043E\u0442\u043E\u0440\u044B\u0445 \u0431\u0443\u0434\u0435\u0442 \u0434\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u043E: %d
diff --git a/src/main/resources/locale_uk_UA.properties b/src/main/resources/locale_uk_UA.properties
index b5072e2..0152896 100644
--- a/src/main/resources/locale_uk_UA.properties
+++ b/src/main/resources/locale_uk_UA.properties
@@ -71,3 +71,5 @@ tab2_Cb_GlVersion=\u0412\u0435\u0440\u0441\u0456\u044F GoldLeaf
windowBodyPleaseStopOtherProcessFirst=\u0411\u0443\u0434\u044C \u043B\u0430\u0441\u043A\u0430, \u0437\u0443\u043F\u0438\u043D\u0456\u0442\u044C \u0456\u043D\u0448\u0438\u0439 \u0430\u043A\u0442\u0438\u0432\u043D\u0438\u0439 \u043F\u0440\u043E\u0446\u0435\u0441 \u043F\u0435\u0440\u0448 \u043D\u0456\u0436 \u043F\u0440\u043E\u0434\u043E\u0432\u0436\u0438\u0442\u0438.
tab2_Cb_foldersSelectorForRomsDesc=\u0417\u043C\u0456\u043D\u044E\u0454 \u043F\u043E\u0432\u0435\u0434\u0456\u043D\u043A\u0443 \u043A\u043D\u043E\u043F\u043A\u0438 \u043A\u043D\u043E\u043F\u043A\u0438 "\u0412\u0438\u0431\u0440\u0430\u0442\u0438 \u0444\u0430\u0439\u043B\u0438" \u043D\u0430 \u0432\u043A\u043B\u0430\u0434\u0446\u0456 '\u0406\u0433\u0440\u0438'. \u0417\u0430\u043C\u0456\u0441\u0442\u044C \u0432\u0438\u0431\u043E\u0440\u0443 ROM \u0444\u0430\u0439\u043B\u0456\u0432 \u043E\u0434\u0438\u043D \u0437\u0430 \u043E\u0434\u043D\u0438\u043C \u0432\u0438 \u0432\u043A\u0430\u0437\u0443\u0454\u0442\u0435 \u043F\u0430\u043F\u043A\u0443, \u043F\u0456\u0441\u043B\u044F \u0447\u043E\u0433\u043E \u0434\u043E\u0434\u0430\u044E\u0442\u044C\u0441\u044F \u0443\u0441\u0456 \u0444\u0430\u0439\u043B\u0438, \u0449\u043E \u043F\u0456\u0434\u0442\u0440\u0438\u043C\u0443\u044E\u0442\u044C\u0441\u044F.
tab2_Cb_foldersSelectorForRoms=\u0412\u0438\u0431\u0438\u0440\u0430\u0442\u0438 \u043F\u0430\u043F\u043A\u0443 \u0437 ROM \u0444\u0430\u0439\u043B\u0430\u043C\u0438 \u0437\u0430\u043C\u0456\u0441\u0442\u044C \u0432\u0438\u0431\u043E\u0440\u0443 \u0444\u0430\u0439\u043B\u0456\u0432 \u043F\u043E\u043E\u0434\u0438\u043D\u0446\u0456.
+windowTitleAddingFiles=\u0428\u0443\u043A\u0430\u0454\u043C\u043E \u0444\u0430\u0439\u043B\u0438...
+windowBodyFilesScanned=\u0424\u0430\u0439\u043B\u0456\u0432 \u043F\u0440\u043E\u0441\u043A\u0430\u043D\u043E\u0432\u0430\u043D\u043E: %d\n\u0417 \u044F\u043A\u0438\u0445 \u0431\u0443\u0434\u0435 \u0434\u043E\u0434\u0430\u043D\u043E: %d
diff --git a/src/main/resources/res/app_dark.css b/src/main/resources/res/app_dark.css
index 807a88f..5ee4192 100644
--- a/src/main/resources/res/app_dark.css
+++ b/src/main/resources/res/app_dark.css
@@ -78,6 +78,10 @@
-fx-padding: 0.23em;
}
+.progress-indicator {
+ -fx-progress-color: #00bce4;
+}
+
.dialog-pane {
-fx-background-color: #4f4f4f;
}
@@ -131,7 +135,7 @@
}
-// -======================== TAB PANE =========================-
+/* -======================== TAB PANE =========================- */
.tab-pane .tab SVGPath{
-fx-fill: #f7fafa;
}
diff --git a/src/main/resources/res/app_light.css b/src/main/resources/res/app_light.css
index c13c160..fde9c6a 100644
--- a/src/main/resources/res/app_light.css
+++ b/src/main/resources/res/app_light.css
@@ -24,7 +24,7 @@
-fx-effect: dropshadow(three-pass-box, #00caca, 2, 0, 0, 0);
}
.button:focused, .buttonStop:focused, .buttonUp:focused, .buttonSelect:focused, .choice-box:focused{
- -fx-background-color: #cccccc;
+ -fx-background-color: #fefefe;
-fx-background-insets: 0 0 0 0, 0, 1, 2;
-fx-border-color: #cccccc;
-fx-border-radius: 3;
@@ -95,6 +95,10 @@
-fx-padding: 0.23em;
}
+.progress-indicator {
+ -fx-progress-color: #00bce4;
+}
+
.dialog-pane {
-fx-background-color: #fefefe;
}
@@ -183,9 +187,9 @@
.tab-pane > .tab-header-area > .tab-header-background
{
- -fx-background-color: #ebebeb;
-
+ -fx-background-color: linear-gradient(to right, #ebebeb 0%, #fefefe 7.5%, #fefefe 100%);
}
+
.tab-pane > .tab-header-area > .headers-region > .tab {
-fx-padding: 10;
}
@@ -220,7 +224,7 @@
-fx-text-fill: #2c2c2c;
}
.table-row-cell, .table-row-cell:filled:selected, .table-row-cell:selected{
- -fx-background-color: -fx-table-cell-border-color, #d3fffd;
+ -fx-background-color: -fx-table-cell-border-color, #ebfffe;
-fx-background-insets: 0, 0 0 1 0;
-fx-padding: 0.0em; /* 0 */
-fx-table-cell-border-color: #b0b0b0;