Skip to content

Commit 503aa8c

Browse files
committed
allows adding files and folders via filechooser and drag and drop
need to switch to JFileChooser, as javafx filechooser doesnt allow files+folders selection selection folders (filechooser/dragndrop) now recursively walks the directory and adds every file.xyz it finds
1 parent 9a42e42 commit 503aa8c

File tree

1 file changed

+98
-34
lines changed

1 file changed

+98
-34
lines changed

src/main/java/nsusbloader/Controllers/GamesController.java

Lines changed: 98 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import javafx.scene.layout.AnchorPane;
2929
import javafx.scene.layout.Region;
3030
import javafx.stage.DirectoryChooser;
31-
import javafx.stage.FileChooser;
3231
import nsusbloader.AppPreferences;
3332
import nsusbloader.com.net.NETCommunications;
3433
import nsusbloader.com.usb.UsbCommunications;
@@ -40,11 +39,22 @@
4039

4140
import java.io.File;
4241
import java.net.URL;
42+
import java.util.ArrayList;
43+
import java.util.Arrays;
4344
import java.util.LinkedList;
4445
import java.util.List;
4546
import java.util.ResourceBundle;
4647

48+
import javax.swing.JFileChooser;
49+
import javax.swing.UIManager;
50+
import javax.swing.UnsupportedLookAndFeelException;
51+
import javax.swing.filechooser.FileFilter;
52+
4753
public class GamesController implements Initializable {
54+
55+
private static final String REGEX_ONLY_NSP = ".*\\.nsp$";
56+
private static final String REGEX_ALLFILES_TINFOIL = ".*\\.(nsp$|xci$|nsz$|xcz$)";
57+
4858
@FXML
4959
private AnchorPane usbNetPane;
5060

@@ -186,32 +196,88 @@ String getNsIp(){
186196
return nsIpTextField.getText();
187197
}
188198

199+
200+
private boolean isGoldLeaf() {
201+
return getSelectedProtocol().equals("GoldLeaf")
202+
&& (!MediatorControl.getInstance().getContoller().getSettingsCtrlr().getGoldleafSettings().getNSPFileFilterForGL());
203+
}
204+
205+
private boolean isTinfoil() {
206+
return getSelectedProtocol().equals("TinFoil")
207+
&& MediatorControl.getInstance().getContoller().getSettingsCtrlr().getTinfoilSettings().isXciNszXczSupport();
208+
}
209+
210+
private String getRegexForFiles() {
211+
if (isTinfoil())
212+
return REGEX_ALLFILES_TINFOIL;
213+
else if (isGoldLeaf())
214+
return REGEX_ONLY_NSP;
215+
else
216+
return REGEX_ONLY_NSP;
217+
}
218+
189219
/**
190220
* Functionality for selecting NSP button.
191221
* */
192222
private void selectFilesBtnAction(){
193-
List<File> filesList;
194-
FileChooser fileChooser = new FileChooser();
195-
fileChooser.setTitle(resourceBundle.getString("btn_OpenFile"));
196-
197-
fileChooser.setInitialDirectory(new File(FilesHelper.getRealFolder(previouslyOpenedPath)));
198-
199-
if (getSelectedProtocol().equals("TinFoil") && MediatorControl.getInstance().getContoller().getSettingsCtrlr().getTinfoilSettings().isXciNszXczSupport())
200-
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("NSP/XCI/NSZ/XCZ", "*.nsp", "*.xci", "*.nsz", "*.xcz"));
201-
else if (getSelectedProtocol().equals("GoldLeaf") && (! MediatorControl.getInstance().getContoller().getSettingsCtrlr().getGoldleafSettings().getNSPFileFilterForGL()))
202-
fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("Any file", "*.*"),
203-
new FileChooser.ExtensionFilter("NSP ROM", "*.nsp")
204-
);
205-
else
206-
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("NSP ROM", "*.nsp"));
223+
final String regex = getRegexForFiles();
224+
if(!UIManager.getLookAndFeel().isNativeLookAndFeel()) {
225+
try {
226+
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
227+
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
228+
// :shrug emoji:
229+
// defaults to Metal Look and Feel
230+
}
231+
}
207232

208-
filesList = fileChooser.showOpenMultipleDialog(usbNetPane.getScene().getWindow());
209-
if (filesList != null && !filesList.isEmpty()) {
210-
tableFilesListController.setFiles(filesList);
211-
uploadStopBtn.setDisable(false);
212-
previouslyOpenedPath = filesList.get(0).getParent();
233+
JFileChooser fileChooser = new JFileChooser(new File(FilesHelper.getRealFolder(previouslyOpenedPath)));
234+
fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
235+
fileChooser.setMultiSelectionEnabled(true);
236+
fileChooser.setFileFilter(new FileFilter() {
237+
public String getDescription() {
238+
return "Switch Files";
239+
}
240+
public boolean accept(File f) {
241+
return f.isDirectory() || f.getName().toLowerCase().matches(regex);
242+
}
243+
});
244+
245+
if(fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
246+
List<File> files = Arrays.asList(fileChooser.getSelectedFiles());
247+
List<File> allFiles = new ArrayList<>();
248+
249+
if (files.size() != 0) {
250+
files.stream().filter(File::isDirectory).forEach(f -> collectFiles(allFiles, f, regex));
251+
files.stream().filter(f -> f.getName().toLowerCase().matches(regex)).forEach(allFiles::add);
252+
}
253+
254+
if (allFiles.size() > 0) {
255+
tableFilesListController.setFiles(allFiles);
256+
uploadStopBtn.setDisable(false);
257+
previouslyOpenedPath = allFiles.get(0).getParent();
258+
}
259+
}
260+
}
261+
262+
/**
263+
* used to recursively walk all directories, every file will be added to the storage list
264+
* @param storage used to hold files
265+
* @param startFolder where to start
266+
* @param regex for filenames
267+
*/
268+
private void collectFiles(List<File> storage, File startFolder, final String regex) {
269+
if (startFolder.isDirectory()) {
270+
File[] files = startFolder.listFiles();
271+
for (File f : files) {
272+
if (f.isDirectory()) {
273+
collectFiles(storage, f, regex);
274+
} else if (f.getName().toLowerCase().matches(regex)) {
275+
storage.add(f);
276+
}
277+
}
213278
}
214279
}
280+
215281
/**
216282
* Functionality for selecting Split NSP button.
217283
* */
@@ -325,20 +391,18 @@ private void handleDragOver(DragEvent event){
325391
* */
326392
@FXML
327393
private void handleDrop(DragEvent event){
328-
List<File> filesDropped = event.getDragboard().getFiles();
329-
SettingsController settingsController = MediatorControl.getInstance().getContoller().getSettingsCtrlr();
330-
SettingsBlockTinfoilController tinfoilSettings = settingsController.getTinfoilSettings();
331-
SettingsBlockGoldleafController goldleafController = settingsController.getGoldleafSettings();
332-
333-
if (getSelectedProtocol().equals("TinFoil") && tinfoilSettings.isXciNszXczSupport())
334-
filesDropped.removeIf(file -> ! file.getName().toLowerCase().matches("(.*\\.nsp$)|(.*\\.xci$)|(.*\\.nsz$)|(.*\\.xcz$)"));
335-
else if (getSelectedProtocol().equals("GoldLeaf") && (! goldleafController.getNSPFileFilterForGL()))
336-
filesDropped.removeIf(file -> (file.isDirectory() && ! file.getName().toLowerCase().matches(".*\\.nsp$")));
337-
else
338-
filesDropped.removeIf(file -> ! file.getName().toLowerCase().matches(".*\\.nsp$"));
339-
340-
if ( ! filesDropped.isEmpty() )
341-
tableFilesListController.setFiles(filesDropped);
394+
final String regex = getRegexForFiles();
395+
396+
List<File> files = event.getDragboard().getFiles();
397+
List<File> allFiles = new ArrayList<>();
398+
399+
if (files.size() != 0) {
400+
files.stream().filter(File::isDirectory).forEach(f -> collectFiles(allFiles, f, regex));
401+
files.stream().filter(f -> f.getName().toLowerCase().matches(regex)).forEach(allFiles::add);
402+
}
403+
404+
if ( ! allFiles.isEmpty() )
405+
tableFilesListController.setFiles(allFiles);
342406

343407
event.setDropCompleted(true);
344408
event.consume();

0 commit comments

Comments
 (0)