mirror of
https://github.com/mitb-archive/filebot
synced 2024-11-16 06:15:02 -05:00
* improved tool panel
This commit is contained in:
parent
a1b118d0f6
commit
683c5e4cee
@ -31,14 +31,6 @@ public class FileFormat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String formatNumberOfFiles(int n) {
|
|
||||||
if (n == 1)
|
|
||||||
return n + " file";
|
|
||||||
else
|
|
||||||
return n + " files";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static boolean hasExtension(File file, String... extensions) {
|
public static boolean hasExtension(File file, String... extensions) {
|
||||||
if (file.isDirectory())
|
if (file.isDirectory())
|
||||||
return false;
|
return false;
|
||||||
|
@ -57,8 +57,8 @@ public class AnalyzePanel extends FileBotPanel {
|
|||||||
fileTreePanel.setMinimumSize(min);
|
fileTreePanel.setMinimumSize(min);
|
||||||
toolsPanel.setMinimumSize(min);
|
toolsPanel.setMinimumSize(min);
|
||||||
|
|
||||||
addTool(new SplitPanel());
|
|
||||||
addTool(new TypePanel());
|
addTool(new TypePanel());
|
||||||
|
addTool(new SplitPanel());
|
||||||
|
|
||||||
fileTreePanel.getFileTree().addPropertyChangeListener(FileTree.CONTENT_PROPERTY, fileTreeChangeListener);
|
fileTreePanel.getFileTree().addPropertyChangeListener(FileTree.CONTENT_PROPERTY, fileTreeChangeListener);
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package net.sourceforge.filebot.ui.panel.analyze;
|
|||||||
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileFilter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.swing.tree.DefaultMutableTreeNode;
|
import javax.swing.tree.DefaultMutableTreeNode;
|
||||||
@ -54,8 +55,13 @@ class FileTreeTransferPolicy extends BackgroundFileTransferablePolicy<DefaultMut
|
|||||||
DefaultMutableTreeNode node = new DefaultMutableTreeNode(file);
|
DefaultMutableTreeNode node = new DefaultMutableTreeNode(file);
|
||||||
|
|
||||||
if (file.isDirectory() && !Thread.currentThread().isInterrupted()) {
|
if (file.isDirectory() && !Thread.currentThread().isInterrupted()) {
|
||||||
// run through file tree
|
// run through folders first
|
||||||
for (File f : file.listFiles()) {
|
for (File f : file.listFiles(FOLDER_FILTER)) {
|
||||||
|
node.add(getTree(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
// then files
|
||||||
|
for (File f : file.listFiles(FILE_FILTER)) {
|
||||||
node.add(getTree(f));
|
node.add(getTree(f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -69,4 +75,22 @@ class FileTreeTransferPolicy extends BackgroundFileTransferablePolicy<DefaultMut
|
|||||||
return "files and folders";
|
return "files and folders";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final FileFilter FOLDER_FILTER = new FileFilter() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean accept(File file) {
|
||||||
|
return file.isDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final FileFilter FILE_FILTER = new FileFilter() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean accept(File file) {
|
||||||
|
return file.isFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,9 @@ import java.awt.BorderLayout;
|
|||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@ -74,96 +76,105 @@ public class SplitPanel extends ToolPanel implements ChangeListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* callback when splitsize has been changed
|
|
||||||
*/
|
|
||||||
public void stateChanged(ChangeEvent e) {
|
public void stateChanged(ChangeEvent e) {
|
||||||
if (files != null)
|
if (fileChache != null) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private long getSplitSize() {
|
private long getSplitSize() {
|
||||||
return spinnerModel.getNumber().intValue() * FileFormat.MEGA;
|
return spinnerModel.getNumber().intValue() * FileFormat.MEGA;
|
||||||
}
|
}
|
||||||
|
|
||||||
private UpdateTask latestUpdateTask;
|
private UpdateTask updateTask;
|
||||||
|
|
||||||
private Collection<File> files;
|
private Collection<File> fileChache;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Collection<File> files) {
|
public void update(Collection<File> files) {
|
||||||
this.files = files;
|
this.fileChache = files;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void update() {
|
private synchronized void update() {
|
||||||
latestUpdateTask = new UpdateTask();
|
if (updateTask != null) {
|
||||||
|
updateTask.cancel(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTask = new UpdateTask(fileChache);
|
||||||
|
|
||||||
tree.firePropertyChange(LoadingOverlayPane.LOADING_PROPERTY, false, true);
|
tree.firePropertyChange(LoadingOverlayPane.LOADING_PROPERTY, false, true);
|
||||||
latestUpdateTask.execute();
|
updateTask.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private class UpdateTask extends SwingWorker<DefaultTreeModel, Object> {
|
private class UpdateTask extends SwingWorker<DefaultTreeModel, Object> {
|
||||||
|
|
||||||
private boolean isLatest() {
|
private final Collection<File> files;
|
||||||
if (this == latestUpdateTask)
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void setLastChildUserObject(DefaultMutableTreeNode root, int part, long size) {
|
public UpdateTask(Collection<File> files) {
|
||||||
DefaultMutableTreeNode node = ((DefaultMutableTreeNode) root.getLastChild());
|
this.files = files;
|
||||||
node.setUserObject(String.format("Part %d (%s)", part, FileFormat.formatSize(size)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DefaultTreeModel doInBackground() throws Exception {
|
protected DefaultTreeModel doInBackground() throws Exception {
|
||||||
long currentSize = 0;
|
|
||||||
|
|
||||||
DefaultMutableTreeNode root = new DefaultMutableTreeNode();
|
List<List<File>> parts = new ArrayList<List<File>>();
|
||||||
DefaultMutableTreeNode first = new DefaultMutableTreeNode();
|
List<File> remainder = new ArrayList<File>();
|
||||||
root.add(first);
|
|
||||||
DefaultMutableTreeNode remainder = new DefaultMutableTreeNode("Remainder");
|
|
||||||
|
|
||||||
int p = 1;
|
|
||||||
long splitSize = getSplitSize();
|
long splitSize = getSplitSize();
|
||||||
|
|
||||||
for (File f : files) {
|
long currentSize = 0;
|
||||||
long fileSize = f.length();
|
List<File> currentPart = null;
|
||||||
DefaultMutableTreeNode fileNode = new DefaultMutableTreeNode(f);
|
|
||||||
|
|
||||||
if (fileSize > splitSize)
|
for (File file : files) {
|
||||||
remainder.add(fileNode);
|
long fileSize = file.length();
|
||||||
else if (currentSize + fileSize <= splitSize) {
|
|
||||||
currentSize += fileSize;
|
|
||||||
((DefaultMutableTreeNode) root.getLastChild()).add(fileNode);
|
|
||||||
} else {
|
|
||||||
setLastChildUserObject(root, p, currentSize);
|
|
||||||
|
|
||||||
currentSize = fileSize;
|
if (fileSize > splitSize) {
|
||||||
p++;
|
remainder.add(file);
|
||||||
DefaultMutableTreeNode node = new DefaultMutableTreeNode();
|
continue;
|
||||||
node.add(fileNode);
|
|
||||||
root.add(node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isLatest())
|
if (currentSize + fileSize > splitSize) {
|
||||||
|
currentSize = 0;
|
||||||
|
currentPart = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentPart == null) {
|
||||||
|
currentPart = new ArrayList<File>();
|
||||||
|
parts.add(currentPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
currentSize += fileSize;
|
||||||
|
currentPart.add(file);
|
||||||
|
|
||||||
|
if (isCancelled()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setLastChildUserObject(root, p, currentSize);
|
DefaultMutableTreeNode root = new DefaultMutableTreeNode();
|
||||||
|
|
||||||
if (!remainder.isLeaf())
|
int count = 1;
|
||||||
root.add(remainder);
|
|
||||||
|
|
||||||
if (first.isLeaf())
|
for (List<File> part : parts) {
|
||||||
first.removeFromParent();
|
root.add(createTreeNode(String.format("Part %d", count), part));
|
||||||
|
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if (isCancelled()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!remainder.isEmpty()) {
|
||||||
|
root.add(createTreeNode("Remainder", remainder));
|
||||||
|
}
|
||||||
|
|
||||||
return new DefaultTreeModel(root);
|
return new DefaultTreeModel(root);
|
||||||
}
|
}
|
||||||
@ -171,13 +182,12 @@ public class SplitPanel extends ToolPanel implements ChangeListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void done() {
|
protected void done() {
|
||||||
try {
|
if (isCancelled()) {
|
||||||
DefaultTreeModel model = get();
|
|
||||||
|
|
||||||
if (model == null)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
tree.setModel(model);
|
try {
|
||||||
|
tree.setModel(get());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// should not happen
|
// should not happen
|
||||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||||
|
@ -6,6 +6,9 @@ import java.io.File;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.tree.DefaultMutableTreeNode;
|
||||||
|
|
||||||
|
import net.sourceforge.filebot.FileFormat;
|
||||||
|
|
||||||
|
|
||||||
public abstract class ToolPanel extends JComponent {
|
public abstract class ToolPanel extends JComponent {
|
||||||
@ -24,4 +27,28 @@ public abstract class ToolPanel extends JComponent {
|
|||||||
|
|
||||||
|
|
||||||
public abstract void update(Collection<File> list);
|
public abstract void update(Collection<File> list);
|
||||||
|
|
||||||
|
|
||||||
|
protected static DefaultMutableTreeNode createTreeNode(String name, Collection<File> files) {
|
||||||
|
DefaultMutableTreeNode node = new DefaultMutableTreeNode();
|
||||||
|
|
||||||
|
long totalSize = 0;
|
||||||
|
|
||||||
|
for (File file : files) {
|
||||||
|
node.add(new DefaultMutableTreeNode(file));
|
||||||
|
totalSize += file.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
String count = null;
|
||||||
|
|
||||||
|
if (files.size() == 1) {
|
||||||
|
count = String.format("%d file", files.size());
|
||||||
|
} else {
|
||||||
|
count = String.format("%d files", files.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
node.setUserObject(String.format("%s (%s, %s)", name, count, FileFormat.formatSize(totalSize)));
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,12 @@ package net.sourceforge.filebot.ui.panel.analyze.tools;
|
|||||||
|
|
||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.SortedMap;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.TreeSet;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@ -42,21 +43,25 @@ public class TypePanel extends ToolPanel {
|
|||||||
tree.setDragEnabled(true);
|
tree.setDragEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private UpdateTask latestUpdateTask;
|
private UpdateTask updateTask = null;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Collection<File> files) {
|
public synchronized void update(Collection<File> files) {
|
||||||
latestUpdateTask = new UpdateTask(files);
|
if (updateTask != null) {
|
||||||
|
updateTask.cancel(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTask = new UpdateTask(files);
|
||||||
|
|
||||||
tree.firePropertyChange(LoadingOverlayPane.LOADING_PROPERTY, false, true);
|
tree.firePropertyChange(LoadingOverlayPane.LOADING_PROPERTY, false, true);
|
||||||
latestUpdateTask.execute();
|
updateTask.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private class UpdateTask extends SwingWorker<DefaultTreeModel, Object> {
|
private class UpdateTask extends SwingWorker<DefaultTreeModel, Object> {
|
||||||
|
|
||||||
private Collection<File> files;
|
private final Collection<File> files;
|
||||||
|
|
||||||
|
|
||||||
public UpdateTask(Collection<File> files) {
|
public UpdateTask(Collection<File> files) {
|
||||||
@ -64,55 +69,37 @@ public class TypePanel extends ToolPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean isLatest() {
|
|
||||||
if (this == latestUpdateTask)
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DefaultTreeModel doInBackground() throws Exception {
|
protected DefaultTreeModel doInBackground() throws Exception {
|
||||||
Map<String, Collection<File>> map = new HashMap<String, Collection<File>>();
|
SortedMap<String, SortedSet<File>> map = new TreeMap<String, SortedSet<File>>();
|
||||||
|
|
||||||
for (File f : files) {
|
for (File file : files) {
|
||||||
String extension = FileFormat.getExtension(f);
|
String extension = FileFormat.getExtension(file);
|
||||||
|
|
||||||
Collection<File> list = map.get(extension);
|
SortedSet<File> set = map.get(extension);
|
||||||
|
|
||||||
if (list != null)
|
if (set == null) {
|
||||||
list.add(f);
|
set = new TreeSet<File>();
|
||||||
else {
|
map.put(extension, set);
|
||||||
list = new ArrayList<File>();
|
|
||||||
list.add(f);
|
|
||||||
map.put(extension, list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isLatest())
|
set.add(file);
|
||||||
|
|
||||||
|
if (isCancelled()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DefaultMutableTreeNode root = new DefaultMutableTreeNode();
|
DefaultMutableTreeNode root = new DefaultMutableTreeNode();
|
||||||
Iterator<String> i = map.keySet().iterator();
|
|
||||||
|
|
||||||
while (i.hasNext()) {
|
for (Map.Entry<String, SortedSet<File>> entry : map.entrySet()) {
|
||||||
String key = i.next();
|
|
||||||
Collection<File> list = map.get(key);
|
|
||||||
DefaultMutableTreeNode node = new DefaultMutableTreeNode();
|
|
||||||
long size = 0;
|
|
||||||
|
|
||||||
for (File f : list) {
|
root.add(createTreeNode(entry.getKey(), entry.getValue()));
|
||||||
node.add(new DefaultMutableTreeNode(f));
|
|
||||||
size += f.length();
|
|
||||||
}
|
|
||||||
|
|
||||||
node.setUserObject(key + " (" + FileFormat.formatNumberOfFiles(list.size()) + ", " + FileFormat.formatSize(size) + ")");
|
if (isCancelled()) {
|
||||||
root.add(node);
|
|
||||||
|
|
||||||
if (!isLatest())
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new DefaultTreeModel(root);
|
return new DefaultTreeModel(root);
|
||||||
}
|
}
|
||||||
@ -120,13 +107,12 @@ public class TypePanel extends ToolPanel {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void done() {
|
protected void done() {
|
||||||
try {
|
if (isCancelled()) {
|
||||||
DefaultTreeModel model = get();
|
|
||||||
|
|
||||||
if (model == null)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
tree.setModel(model);
|
try {
|
||||||
|
tree.setModel(get());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// should not happen
|
// should not happen
|
||||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||||
|
Loading…
Reference in New Issue
Block a user