Refactor Filter / Tools
This commit is contained in:
parent
fcf3bd75f2
commit
8656af9508
|
@ -8,6 +8,7 @@ import java.awt.Color;
|
|||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CancellationException;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JScrollPane;
|
||||
|
@ -48,10 +49,10 @@ class AttributeTool extends Tool<TableModel> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected TableModel createModelInBackground(File root) {
|
||||
protected TableModel createModelInBackground(List<File> root) {
|
||||
FileAttributesTableModel model = new FileAttributesTableModel();
|
||||
|
||||
if (root == null) {
|
||||
if (root.isEmpty()) {
|
||||
return model;
|
||||
}
|
||||
|
||||
|
@ -74,6 +75,10 @@ class AttributeTool extends Tool<TableModel> {
|
|||
model.addRow(String.format("%s::%d", "OMDb", movie.getImdbId()), metaObject, originalName, file);
|
||||
}
|
||||
}
|
||||
|
||||
if (Thread.interrupted()) {
|
||||
throw new CancellationException();
|
||||
}
|
||||
}
|
||||
|
||||
return model;
|
||||
|
|
|
@ -2,11 +2,10 @@ package net.filebot.ui.filter;
|
|||
|
||||
import static net.filebot.Logging.*;
|
||||
import static net.filebot.UserFiles.*;
|
||||
import static net.filebot.util.ExceptionUtilities.*;
|
||||
import static net.filebot.util.FileUtilities.*;
|
||||
import static net.filebot.util.ui.SwingUI.*;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.util.ArrayList;
|
||||
|
@ -21,7 +20,6 @@ import java.util.function.Consumer;
|
|||
import java.util.function.Supplier;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JScrollPane;
|
||||
|
@ -76,8 +74,8 @@ class ExtractTool extends Tool<TableModel> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected TableModel createModelInBackground(File root) throws InterruptedException {
|
||||
if (root == null) {
|
||||
protected TableModel createModelInBackground(List<File> root) throws Exception {
|
||||
if (root.isEmpty()) {
|
||||
return new ArchiveEntryModel();
|
||||
}
|
||||
|
||||
|
@ -85,46 +83,34 @@ class ExtractTool extends Tool<TableModel> {
|
|||
List<File> files = listFiles(root, Archive.VOLUME_ONE_FILTER, HUMAN_NAME_ORDER);
|
||||
List<ArchiveEntry> entries = new ArrayList<ArchiveEntry>();
|
||||
|
||||
try {
|
||||
for (File file : files) {
|
||||
try (Archive archive = Archive.open(file)) {
|
||||
for (FileInfo it : archive.listFiles()) {
|
||||
entries.add(new ArchiveEntry(file, it));
|
||||
}
|
||||
for (File file : files) {
|
||||
try (Archive archive = Archive.open(file)) {
|
||||
for (FileInfo it : archive.listFiles()) {
|
||||
entries.add(new ArchiveEntry(file, it));
|
||||
}
|
||||
}
|
||||
|
||||
// unwind thread, if we have been cancelled
|
||||
if (Thread.interrupted()) {
|
||||
throw new InterruptedException();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// unwind thread, if we have been cancelled
|
||||
if (findCause(e, InterruptedException.class) != null) {
|
||||
throw findCause(e, InterruptedException.class);
|
||||
if (Thread.interrupted()) {
|
||||
throw new CancellationException();
|
||||
}
|
||||
log.log(Level.WARNING, e.getMessage(), e);
|
||||
}
|
||||
|
||||
return new ArchiveEntryModel(entries);
|
||||
}
|
||||
|
||||
private Action extractAction = new AbstractAction("Extract All", ResourceManager.getIcon("package.extract")) {
|
||||
private Action extractAction = newAction("Extract All", ResourceManager.getIcon("package.extract"), evt -> {
|
||||
List<File> archives = ((ArchiveEntryModel) table.getModel()).getArchiveList();
|
||||
if (archives.isEmpty())
|
||||
return;
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
final List<File> archives = ((ArchiveEntryModel) table.getModel()).getArchiveList();
|
||||
if (archives.isEmpty())
|
||||
return;
|
||||
File selectedFile = showOpenDialogSelectFolder(archives.get(0).getParentFile(), "Extract to ...", evt);
|
||||
if (selectedFile == null)
|
||||
return;
|
||||
|
||||
File selectedFile = showOpenDialogSelectFolder(archives.get(0).getParentFile(), "Extract to ...", evt);
|
||||
if (selectedFile == null)
|
||||
return;
|
||||
|
||||
ExtractWorker worker = new ExtractWorker(archives, selectedFile, null, true, ConflictAction.AUTO);
|
||||
ProgressMonitor.runTask("Extract", "Extracting files...", worker);
|
||||
}
|
||||
};
|
||||
ExtractWorker worker = new ExtractWorker(archives, selectedFile, null, true, ConflictAction.AUTO);
|
||||
ProgressMonitor.runTask("Extract", "Extracting files...", worker);
|
||||
});
|
||||
|
||||
private static class ArchiveEntry {
|
||||
|
||||
|
@ -199,7 +185,7 @@ class ExtractTool extends Tool<TableModel> {
|
|||
|
||||
}
|
||||
|
||||
protected static class ExtractWorker implements ProgressWorker<Void> {
|
||||
private static class ExtractWorker implements ProgressWorker<Void> {
|
||||
|
||||
private final File[] archives;
|
||||
private final File outputFolder;
|
||||
|
|
|
@ -8,7 +8,6 @@ import java.awt.event.ActionEvent;
|
|||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
|
@ -54,8 +53,20 @@ public class FileTree extends JTree {
|
|||
return (DefaultTreeModel) super.getModel();
|
||||
}
|
||||
|
||||
public FolderNode getRoot() {
|
||||
return (FolderNode) getModel().getRoot();
|
||||
public List<File> getRoot() {
|
||||
FolderNode model = (FolderNode) getModel().getRoot();
|
||||
|
||||
return model.getChildren().stream().map(node -> {
|
||||
if (node instanceof FolderNode) {
|
||||
FolderNode folder = (FolderNode) node;
|
||||
return folder.getFile();
|
||||
}
|
||||
if (node instanceof FileNode) {
|
||||
FileNode file = (FileNode) node;
|
||||
return file.getFile();
|
||||
}
|
||||
return null;
|
||||
}).collect(toList());
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
|
@ -258,15 +269,16 @@ public class FileTree extends JTree {
|
|||
private final String title;
|
||||
private final List<TreeNode> children;
|
||||
|
||||
/**
|
||||
* Creates a root node (no parent, no title, empty list of children)
|
||||
*/
|
||||
public FolderNode() {
|
||||
this(null, "", new ArrayList<TreeNode>(0));
|
||||
this(emptyList()); // empty root node
|
||||
}
|
||||
|
||||
public FolderNode(List<TreeNode> children) {
|
||||
this(null, "/", children); // root node
|
||||
}
|
||||
|
||||
public FolderNode(String title, List<TreeNode> children) {
|
||||
this(null, title, children);
|
||||
this(null, title, children); // virtual node
|
||||
}
|
||||
|
||||
public FolderNode(File file, String title, List<TreeNode> children) {
|
||||
|
@ -318,8 +330,9 @@ public class FileTree extends JTree {
|
|||
|
||||
@Override
|
||||
protected Iterator<TreeNode> children(TreeNode node) {
|
||||
if (node instanceof FolderNode)
|
||||
if (node instanceof FolderNode) {
|
||||
return ((FolderNode) node).getChildren().iterator();
|
||||
}
|
||||
|
||||
// can't step into non-folder nodes
|
||||
return null;
|
||||
|
@ -333,8 +346,9 @@ public class FileTree extends JTree {
|
|||
|
||||
@Override
|
||||
protected File filter(TreeNode node) {
|
||||
if (node instanceof FileNode)
|
||||
if (node instanceof FileNode) {
|
||||
return ((FileNode) node).getFile();
|
||||
}
|
||||
|
||||
// filter out non-file nodes
|
||||
return null;
|
||||
|
|
|
@ -63,8 +63,10 @@ class FileTreePanel extends JComponent {
|
|||
fireFileTreeChange();
|
||||
});
|
||||
|
||||
public static final String FILE_TREE_PROPERTY = "FILE_TREE";
|
||||
|
||||
private void fireFileTreeChange() {
|
||||
firePropertyChange("filetree", null, fileTree);
|
||||
firePropertyChange(FILE_TREE_PROPERTY, null, fileTree);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,14 +2,15 @@ package net.filebot.ui.filter;
|
|||
|
||||
import static net.filebot.Logging.*;
|
||||
import static net.filebot.Settings.*;
|
||||
import static net.filebot.util.ExceptionUtilities.*;
|
||||
import static net.filebot.util.FileUtilities.*;
|
||||
import static net.filebot.util.ui.SwingUI.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javax.swing.tree.TreeNode;
|
||||
|
@ -18,7 +19,6 @@ import net.filebot.mac.MacAppUtilities;
|
|||
import net.filebot.ui.filter.FileTree.FileNode;
|
||||
import net.filebot.ui.filter.FileTree.FolderNode;
|
||||
import net.filebot.ui.transfer.BackgroundFileTransferablePolicy;
|
||||
import net.filebot.util.ExceptionUtilities;
|
||||
import net.filebot.util.FastFile;
|
||||
|
||||
class FileTreeTransferablePolicy extends BackgroundFileTransferablePolicy<TreeNode> {
|
||||
|
@ -42,46 +42,36 @@ class FileTreeTransferablePolicy extends BackgroundFileTransferablePolicy<TreeNo
|
|||
|
||||
@Override
|
||||
protected void process(List<TreeNode> root) {
|
||||
tree.getModel().setRoot(root.get(0));
|
||||
tree.getModel().setRoot(new FolderNode(root));
|
||||
tree.getModel().reload();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void process(Exception e) {
|
||||
log.log(Level.WARNING, ExceptionUtilities.getRootCauseMessage(e), e);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleInBackground(List<File> files, TransferAction action) {
|
||||
super.handleInBackground(files, action);
|
||||
log.log(Level.WARNING, getRootCauseMessage(e), e);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void load(List<File> files, TransferAction action) {
|
||||
// make sure we have access to the parent folder structure, not just the dropped file
|
||||
if (isMacSandbox()) {
|
||||
MacAppUtilities.askUnlockFolders(getWindow(tree), files);
|
||||
}
|
||||
|
||||
try {
|
||||
if (files.size() > 1 || containsOnly(files, FILES)) {
|
||||
files = Arrays.asList(files.get(0).getParentFile());
|
||||
}
|
||||
|
||||
// make sure we have access to the parent folder structure, not just the dropped file
|
||||
if (isMacSandbox()) {
|
||||
MacAppUtilities.askUnlockFolders(getWindow(tree), files);
|
||||
}
|
||||
|
||||
// use fast file to minimize system calls like length(), isDirectory(), isFile(), ...
|
||||
FastFile root = new FastFile(filter(files, FOLDERS).get(0));
|
||||
TreeNode[] node = files.stream().map(FastFile::new).map(this::getTreeNode).toArray(TreeNode[]::new);
|
||||
|
||||
// publish on EDT
|
||||
TreeNode[] node = { getTreeNode(root) };
|
||||
publish(node);
|
||||
} catch (InterruptedException e) {
|
||||
} catch (CancellationException e) {
|
||||
// supposed to happen if background execution was aborted
|
||||
}
|
||||
}
|
||||
|
||||
private TreeNode getTreeNode(File file) throws InterruptedException {
|
||||
private TreeNode getTreeNode(File file) {
|
||||
if (Thread.interrupted()) {
|
||||
throw new InterruptedException();
|
||||
throw new CancellationException();
|
||||
}
|
||||
|
||||
if (file.isDirectory()) {
|
||||
|
|
|
@ -21,11 +21,11 @@ public class FilterPanel extends JComponent {
|
|||
add(fileTreePanel, "grow 1, w 300:pref:500");
|
||||
add(toolsPanel, "grow 2");
|
||||
|
||||
fileTreePanel.addPropertyChangeListener("filetree", evt -> {
|
||||
fileTreePanel.addPropertyChangeListener(FileTreePanel.FILE_TREE_PROPERTY, evt -> {
|
||||
// stopped loading, refresh tools
|
||||
for (int i = 0; i < toolsPanel.getTabCount(); i++) {
|
||||
Tool<?> tool = (Tool<?>) toolsPanel.getComponentAt(i);
|
||||
tool.updateRoot(fileTreePanel.getFileTree().getRoot().getFile());
|
||||
tool.setRoot(fileTreePanel.getFileTree().getRoot());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
|
@ -53,8 +54,8 @@ class MediaInfoTool extends Tool<TableModel> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected TableModel createModelInBackground(File root) {
|
||||
if (root == null) {
|
||||
protected TableModel createModelInBackground(List<File> root) {
|
||||
if (root.isEmpty()) {
|
||||
return new MediaInfoTableModel();
|
||||
}
|
||||
|
||||
|
@ -74,9 +75,13 @@ class MediaInfoTool extends Tool<TableModel> {
|
|||
});
|
||||
});
|
||||
} catch (IllegalArgumentException e) {
|
||||
debug.finest(e.getMessage());
|
||||
debug.finest(e::toString);
|
||||
} catch (Exception e) {
|
||||
debug.warning(e.getMessage());
|
||||
debug.warning(e::toString);
|
||||
}
|
||||
|
||||
if (Thread.interrupted()) {
|
||||
throw new CancellationException();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -7,13 +7,12 @@ import java.awt.Color;
|
|||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CancellationException;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSpinner;
|
||||
import javax.swing.SpinnerNumberModel;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import javax.swing.tree.DefaultTreeModel;
|
||||
import javax.swing.tree.TreeModel;
|
||||
import javax.swing.tree.TreeNode;
|
||||
|
@ -51,14 +50,11 @@ class SplitTool extends Tool<TreeModel> {
|
|||
tree.setTransferHandler(new DefaultTransferHandler(null, new FileTreeExportHandler()));
|
||||
tree.setDragEnabled(true);
|
||||
|
||||
spinnerModel.addChangeListener(new ChangeListener() {
|
||||
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent evt) {
|
||||
// update model in foreground, will be much faster than the initial load because length() is cached now
|
||||
if (getRoot() != null) {
|
||||
updateRoot(getRoot());
|
||||
}
|
||||
// update model in foreground, will be much faster than the initial load because length() is cached now
|
||||
spinnerModel.addChangeListener(evt -> {
|
||||
List<File> root = getRoot();
|
||||
if (root.size() > 0) {
|
||||
setRoot(root);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -68,8 +64,8 @@ class SplitTool extends Tool<TreeModel> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected TreeModel createModelInBackground(File root) throws InterruptedException {
|
||||
if (root == null) {
|
||||
protected TreeModel createModelInBackground(List<File> root) {
|
||||
if (root.isEmpty()) {
|
||||
return new DefaultTreeModel(new FolderNode("Volumes", emptyList()));
|
||||
}
|
||||
|
||||
|
@ -93,7 +89,7 @@ class SplitTool extends Tool<TreeModel> {
|
|||
|
||||
if (totalSize + fileSize > splitSize) {
|
||||
// part is full, add node and start with next one
|
||||
rootGroup.add(createStatisticsNode(String.format("Disk %d", nextPart++), currentPart));
|
||||
rootGroup.add(createStatisticsNode(nextPart++, currentPart));
|
||||
|
||||
// reset total size and file list
|
||||
totalSize = 0;
|
||||
|
@ -102,11 +98,15 @@ class SplitTool extends Tool<TreeModel> {
|
|||
|
||||
totalSize += fileSize;
|
||||
currentPart.add(f);
|
||||
|
||||
if (Thread.interrupted()) {
|
||||
throw new CancellationException();
|
||||
}
|
||||
}
|
||||
|
||||
if (!currentPart.isEmpty()) {
|
||||
// add last part
|
||||
rootGroup.add(createStatisticsNode(String.format("Disk %d", nextPart++), currentPart));
|
||||
rootGroup.add(createStatisticsNode(nextPart++, currentPart));
|
||||
}
|
||||
|
||||
if (!remainder.isEmpty()) {
|
||||
|
@ -121,4 +121,9 @@ class SplitTool extends Tool<TreeModel> {
|
|||
tree.setModel(model);
|
||||
}
|
||||
|
||||
protected FolderNode createStatisticsNode(int disk, List<File> files) {
|
||||
System.out.println(files);
|
||||
return createStatisticsNode(String.format("Disk %,d", disk), files);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,60 +1,66 @@
|
|||
package net.filebot.ui.filter;
|
||||
|
||||
import static java.util.Collections.*;
|
||||
import static java.util.stream.Collectors.*;
|
||||
import static net.filebot.Logging.*;
|
||||
import static net.filebot.util.ExceptionUtilities.*;
|
||||
import static net.filebot.util.FileUtilities.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.SwingWorker;
|
||||
import javax.swing.tree.TreeNode;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import net.filebot.ui.filter.FileTree.FileNode;
|
||||
import net.filebot.ui.filter.FileTree.FolderNode;
|
||||
import net.filebot.util.ExceptionUtilities;
|
||||
import net.filebot.util.FileUtilities;
|
||||
import net.filebot.util.ui.LoadingOverlayPane;
|
||||
|
||||
abstract class Tool<M> extends JComponent {
|
||||
|
||||
private UpdateModelTask updateTask = null;
|
||||
private File root = null;
|
||||
private List<File> root = emptyList();
|
||||
|
||||
private UpdateModelTask updateTask;
|
||||
|
||||
public Tool(String name) {
|
||||
setName(name);
|
||||
}
|
||||
|
||||
public File getRoot() {
|
||||
public List<File> getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
public void updateRoot(File root) {
|
||||
public void setRoot(List<File> root) {
|
||||
this.root = root;
|
||||
|
||||
if (updateTask != null) {
|
||||
updateTask.cancel(true);
|
||||
}
|
||||
|
||||
Tool.this.firePropertyChange(LoadingOverlayPane.LOADING_PROPERTY, false, true);
|
||||
setLoading(true);
|
||||
|
||||
updateTask = new UpdateModelTask(root);
|
||||
updateTask.execute();
|
||||
}
|
||||
|
||||
protected abstract M createModelInBackground(File root) throws InterruptedException;
|
||||
protected void setLoading(boolean loading) {
|
||||
firePropertyChange(LoadingOverlayPane.LOADING_PROPERTY, !loading, loading);
|
||||
}
|
||||
|
||||
protected abstract M createModelInBackground(List<File> root) throws Exception;
|
||||
|
||||
protected abstract void setModel(M model);
|
||||
|
||||
private class UpdateModelTask extends SwingWorker<M, Void> {
|
||||
|
||||
private final File root;
|
||||
private final List<File> root;
|
||||
|
||||
public UpdateModelTask(File root) {
|
||||
public UpdateModelTask(List<File> root) {
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
|
@ -66,7 +72,7 @@ abstract class Tool<M> extends JComponent {
|
|||
@Override
|
||||
protected void done() {
|
||||
if (this == updateTask) {
|
||||
Tool.this.firePropertyChange(LoadingOverlayPane.LOADING_PROPERTY, true, false);
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
// update task will only be cancelled if a newer update task has been started
|
||||
|
@ -74,14 +80,12 @@ abstract class Tool<M> extends JComponent {
|
|||
try {
|
||||
setModel(get());
|
||||
} catch (Exception e) {
|
||||
Throwable cause = ExceptionUtilities.getRootCause(e);
|
||||
Throwable cause = getRootCause(e);
|
||||
|
||||
if (cause instanceof ConcurrentModificationException || cause instanceof InterruptedException) {
|
||||
// if it happens, it is supposed to
|
||||
debug.log(Level.FINEST, e.getMessage(), e);
|
||||
if (cause instanceof InterruptedException || cause instanceof CancellationException) {
|
||||
debug.log(Level.FINEST, e, e::toString); // if it happens, it is supposed to
|
||||
} else {
|
||||
// should not happen
|
||||
debug.log(Level.WARNING, e.getMessage(), e);
|
||||
debug.log(Level.WARNING, e, e::toString); // should not happen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -89,26 +93,17 @@ abstract class Tool<M> extends JComponent {
|
|||
}
|
||||
|
||||
protected List<TreeNode> createFileNodes(Collection<File> files) {
|
||||
List<TreeNode> nodes = new ArrayList<TreeNode>(files.size());
|
||||
for (File f : files) {
|
||||
nodes.add(new FileNode(f));
|
||||
}
|
||||
return nodes;
|
||||
return files.stream().map(FileNode::new).collect(toList());
|
||||
}
|
||||
|
||||
protected FolderNode createStatisticsNode(String name, List<File> files) {
|
||||
long totalCount = 0;
|
||||
long totalSize = 0;
|
||||
|
||||
for (File f : files) {
|
||||
totalCount += FileUtilities.listFiles(f, FileUtilities.FILES).size();
|
||||
totalSize += FileUtils.sizeOf(f);
|
||||
}
|
||||
List<File> selection = listFiles(files, FILES, null);
|
||||
long size = selection.stream().mapToLong(File::length).sum();
|
||||
|
||||
// set node text (e.g. txt (1 file, 42 Byte))
|
||||
String title = String.format("%s (%,d %s, %s)", name, totalCount, totalCount == 1 ? "file" : "files", FileUtilities.formatSize(totalSize));
|
||||
String title = String.format("%s (%,d %s, %s)", name, selection.size(), selection.size() == 1 ? "file" : "files", FileUtilities.formatSize(size));
|
||||
|
||||
return new FolderNode(null, title, createFileNodes(files));
|
||||
return new FolderNode(title, createFileNodes(files));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.util.LinkedHashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
|
||||
|
@ -44,12 +45,13 @@ class TypeTool extends Tool<TreeModel> {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected TreeModel createModelInBackground(File root) throws InterruptedException {
|
||||
if (root == null) {
|
||||
protected TreeModel createModelInBackground(List<File> root) {
|
||||
if (root.isEmpty()) {
|
||||
return new DefaultTreeModel(new FolderNode("Types", emptyList()));
|
||||
}
|
||||
|
||||
List<File> filesAndFolders = listFiles(root, NOT_HIDDEN, HUMAN_NAME_ORDER);
|
||||
|
||||
List<TreeNode> groups = new ArrayList<TreeNode>();
|
||||
|
||||
for (Entry<String, FileFilter> it : getMetaTypes().entrySet()) {
|
||||
|
@ -57,15 +59,24 @@ class TypeTool extends Tool<TreeModel> {
|
|||
if (selection.size() > 0) {
|
||||
groups.add(createStatisticsNode(it.getKey(), selection));
|
||||
}
|
||||
|
||||
if (Thread.interrupted()) {
|
||||
throw new CancellationException();
|
||||
}
|
||||
}
|
||||
|
||||
SortedMap<String, TreeNode> extensionGroups = new TreeMap<String, TreeNode>(String.CASE_INSENSITIVE_ORDER);
|
||||
for (Entry<String, List<File>> it : mapByExtension(filter(filesAndFolders, FILES)).entrySet()) {
|
||||
if (it.getKey() == null)
|
||||
continue;
|
||||
|
||||
extensionGroups.put(it.getKey(), createStatisticsNode(it.getKey(), it.getValue()));
|
||||
for (Entry<String, List<File>> it : mapByExtension(filter(filesAndFolders, FILES)).entrySet()) {
|
||||
if (it.getKey() != null) {
|
||||
extensionGroups.put(it.getKey(), createStatisticsNode(it.getKey(), it.getValue()));
|
||||
}
|
||||
|
||||
if (Thread.interrupted()) {
|
||||
throw new CancellationException();
|
||||
}
|
||||
}
|
||||
|
||||
groups.addAll(extensionGroups.values());
|
||||
|
||||
// create tree model
|
||||
|
|
Loading…
Reference in New Issue