* support dropping of large / slow folders into Rename panel (Files list)

This commit is contained in:
Reinhard Pointner 2014-07-27 18:23:45 +00:00
parent 124e7471db
commit 98633f7364
6 changed files with 59 additions and 61 deletions

View File

@ -7,7 +7,6 @@ import java.text.ParseException;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.swing.BorderFactory;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import javax.swing.JSpinner.DefaultEditor; import javax.swing.JSpinner.DefaultEditor;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;

View File

@ -1,6 +1,7 @@
package net.filebot.ui.rename; package net.filebot.ui.rename;
import static net.filebot.MediaTypes.*; import static net.filebot.MediaTypes.*;
import static net.filebot.ui.NotificationLogging.*;
import static net.filebot.ui.transfer.FileTransferable.*; import static net.filebot.ui.transfer.FileTransferable.*;
import static net.filebot.util.FileUtilities.*; import static net.filebot.util.FileUtilities.*;
@ -14,10 +15,11 @@ import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import net.filebot.media.MediaDetection; import net.filebot.media.MediaDetection;
import net.filebot.ui.transfer.FileTransferablePolicy; import net.filebot.ui.transfer.BackgroundFileTransferablePolicy;
import net.filebot.util.ExceptionUtilities;
import net.filebot.util.FastFile; import net.filebot.util.FastFile;
class FilesListTransferablePolicy extends FileTransferablePolicy { class FilesListTransferablePolicy extends BackgroundFileTransferablePolicy<File> {
private final List<File> model; private final List<File> model;
@ -93,7 +95,7 @@ class FilesListTransferablePolicy extends FileTransferablePolicy {
} }
} }
model.addAll(FastFile.create(entries)); publish(FastFile.create(entries).toArray(new File[0]));
} }
@Override @Override
@ -101,4 +103,14 @@ class FilesListTransferablePolicy extends FileTransferablePolicy {
return "files and folders"; return "files and folders";
} }
@Override
protected void process(List<File> chunks) {
model.addAll(FastFile.create(chunks));
}
@Override
protected void process(Exception e) {
UILogger.log(Level.WARNING, ExceptionUtilities.getRootCauseMessage(e), e);
}
} }

View File

@ -179,6 +179,10 @@ class RenameListCellRenderer extends DefaultFancyListCellRenderer {
} }
protected float getMatchProbablity(Match<Object, File> match) { protected float getMatchProbablity(Match<Object, File> match) {
if (match.getValue() == null || match.getCandidate() == null) {
return 1; // assume match is ok
}
if (match.getValue() instanceof Episode) { if (match.getValue() instanceof Episode) {
float f = verificationMetric().getSimilarity(match.getValue(), match.getCandidate()); float f = verificationMetric().getSimilarity(match.getValue(), match.getCandidate());
return (f + 1) / 2; // normalize -1..1 to 0..1 return (f + 1) / 2; // normalize -1..1 to 0..1

View File

@ -58,6 +58,7 @@ import net.filebot.media.MediaDetection;
import net.filebot.similarity.Match; import net.filebot.similarity.Match;
import net.filebot.ui.rename.FormatDialog.Mode; import net.filebot.ui.rename.FormatDialog.Mode;
import net.filebot.ui.rename.RenameModel.FormattedFuture; import net.filebot.ui.rename.RenameModel.FormattedFuture;
import net.filebot.ui.transfer.BackgroundFileTransferablePolicy;
import net.filebot.util.PreferencesMap.PreferencesEntry; import net.filebot.util.PreferencesMap.PreferencesEntry;
import net.filebot.util.ui.ActionPopup; import net.filebot.util.ui.ActionPopup;
import net.filebot.util.ui.LoadingOverlayPane; import net.filebot.util.ui.LoadingOverlayPane;
@ -287,7 +288,18 @@ public class RenamePanel extends JComponent {
}); });
setLayout(new MigLayout("fill, insets dialog, gapx 10px", "[fill][align center, pref!][fill]", "align 33%")); setLayout(new MigLayout("fill, insets dialog, gapx 10px", "[fill][align center, pref!][fill]", "align 33%"));
add(filesList, "grow, sizegroupx list"); add(new LoadingOverlayPane(filesList, filesList, "32px", "30px"), "grow, sizegroupx list");
BackgroundFileTransferablePolicy<?> transferablePolicy = (BackgroundFileTransferablePolicy<?>) filesList.getTransferablePolicy();
transferablePolicy.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (BackgroundFileTransferablePolicy.LOADING_PROPERTY.equals(evt.getPropertyName())) {
filesList.firePropertyChange(LoadingOverlayPane.LOADING_PROPERTY, (boolean) evt.getOldValue(), (boolean) evt.getNewValue());
}
}
});
// make buttons larger // make buttons larger
matchButton.setMargin(new Insets(3, 14, 2, 14)); matchButton.setMargin(new Insets(3, 14, 2, 14));

View File

@ -1,7 +1,5 @@
package net.filebot.ui.transfer; package net.filebot.ui.transfer;
import static net.filebot.ui.transfer.FileTransferable.*; import static net.filebot.ui.transfer.FileTransferable.*;
import java.awt.datatransfer.Transferable; import java.awt.datatransfer.Transferable;
@ -15,42 +13,37 @@ import javax.swing.SwingUtilities;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
import javax.swing.event.SwingPropertyChangeSupport; import javax.swing.event.SwingPropertyChangeSupport;
public abstract class BackgroundFileTransferablePolicy<V> extends FileTransferablePolicy { public abstract class BackgroundFileTransferablePolicy<V> extends FileTransferablePolicy {
public static final String LOADING_PROPERTY = "loading"; public static final String LOADING_PROPERTY = "loading";
private final ThreadLocal<BackgroundWorker> threadLocalWorker = new ThreadLocal<BackgroundWorker>(); private final ThreadLocal<BackgroundWorker> threadLocalWorker = new ThreadLocal<BackgroundWorker>();
private final List<BackgroundWorker> workers = new ArrayList<BackgroundWorker>(2); private final List<BackgroundWorker> workers = new ArrayList<BackgroundWorker>(2);
@Override @Override
public void handleTransferable(Transferable tr, TransferAction action) throws Exception { public void handleTransferable(Transferable tr, TransferAction action) throws Exception {
List<File> files = getFilesFromTransferable(tr); List<File> files = getFilesFromTransferable(tr);
if (action != TransferAction.ADD) { if (action != TransferAction.ADD) {
clear(); clear();
} }
prepare(files); prepare(files);
// create and start worker // create and start worker
new BackgroundWorker(files).execute(); new BackgroundWorker(files).execute();
} }
protected void prepare(List<File> files) { protected void prepare(List<File> files) {
} }
@Override @Override
protected void clear() { protected void clear() {
// stop other workers on clear (before starting new worker) // stop other workers on clear (before starting new worker)
reset(); reset();
} }
public void reset() { public void reset() {
synchronized (workers) { synchronized (workers) {
@ -63,52 +56,45 @@ public abstract class BackgroundFileTransferablePolicy<V> extends FileTransferab
} }
} }
} }
public boolean isLoading() { public boolean isLoading() {
synchronized (workers) { synchronized (workers) {
return !workers.isEmpty(); return !workers.isEmpty();
} }
} }
protected abstract void process(List<V> chunks); protected abstract void process(List<V> chunks);
protected abstract void process(Exception exception); protected abstract void process(Exception exception);
protected final void publish(V... chunks) { protected final void publish(V... chunks) {
BackgroundWorker worker = threadLocalWorker.get(); BackgroundWorker worker = threadLocalWorker.get();
if (worker == null) { if (worker == null) {
// fail if a non-background-worker thread is trying to access the thread-local worker object // fail if a non-background-worker thread is trying to access the thread-local worker object
throw new IllegalThreadStateException("Illegal access thread"); throw new IllegalThreadStateException("Illegal access thread");
} }
worker.offer(chunks); worker.offer(chunks);
} }
protected final void publish(final Exception exception) { protected final void publish(final Exception exception) {
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
@Override @Override
public void run() { public void run() {
process(exception); process(exception);
} }
}); });
} }
protected class BackgroundWorker extends SwingWorker<Object, V> { protected class BackgroundWorker extends SwingWorker<Object, V> {
private final List<File> files; private final List<File> files;
public BackgroundWorker(List<File> files) { public BackgroundWorker(List<File> files) {
this.files = files; this.files = files;
// register this worker // register this worker
synchronized (workers) { synchronized (workers) {
if (workers.add(this) && workers.size() == 1) { if (workers.add(this) && workers.size() == 1) {
@ -116,29 +102,26 @@ public abstract class BackgroundFileTransferablePolicy<V> extends FileTransferab
} }
} }
} }
@Override @Override
protected Object doInBackground() throws Exception { protected Object doInBackground() throws Exception {
// associate this worker with the current (background) thread // associate this worker with the current (background) thread
threadLocalWorker.set(this); threadLocalWorker.set(this);
try { try {
load(files); load(files);
} finally { } finally {
threadLocalWorker.remove(); threadLocalWorker.remove();
} }
return null; return null;
} }
public void offer(V... chunks) { public void offer(V... chunks) {
if (!isCancelled()) { if (!isCancelled()) {
publish(chunks); publish(chunks);
} }
} }
@Override @Override
protected void process(List<V> chunks) { protected void process(List<V> chunks) {
@ -146,7 +129,6 @@ public abstract class BackgroundFileTransferablePolicy<V> extends FileTransferab
BackgroundFileTransferablePolicy.this.process(chunks); BackgroundFileTransferablePolicy.this.process(chunks);
} }
} }
@Override @Override
protected void done() { protected void done() {
@ -158,7 +140,7 @@ public abstract class BackgroundFileTransferablePolicy<V> extends FileTransferab
BackgroundFileTransferablePolicy.this.process(e); BackgroundFileTransferablePolicy.this.process(e);
} }
} }
// unregister worker // unregister worker
synchronized (workers) { synchronized (workers) {
if (workers.remove(this) && workers.isEmpty()) { if (workers.remove(this) && workers.isEmpty()) {
@ -167,15 +149,12 @@ public abstract class BackgroundFileTransferablePolicy<V> extends FileTransferab
} }
} }
} }
protected final PropertyChangeSupport swingPropertyChangeSupport = new SwingPropertyChangeSupport(this, true); protected final PropertyChangeSupport swingPropertyChangeSupport = new SwingPropertyChangeSupport(this, true);
public void addPropertyChangeListener(PropertyChangeListener listener) { public void addPropertyChangeListener(PropertyChangeListener listener) {
swingPropertyChangeSupport.addPropertyChangeListener(listener); swingPropertyChangeSupport.addPropertyChangeListener(listener);
} }
public void removePropertyChangeListener(PropertyChangeListener listener) { public void removePropertyChangeListener(PropertyChangeListener listener) {
swingPropertyChangeSupport.removePropertyChangeListener(listener); swingPropertyChangeSupport.removePropertyChangeListener(listener);

View File

@ -1,7 +1,5 @@
package net.filebot.ui.transfer; package net.filebot.ui.transfer;
import static net.filebot.ui.transfer.FileTransferable.*; import static net.filebot.ui.transfer.FileTransferable.*;
import static net.filebot.util.FileUtilities.*; import static net.filebot.util.FileUtilities.*;
@ -11,51 +9,45 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
public abstract class FileTransferablePolicy extends TransferablePolicy { public abstract class FileTransferablePolicy extends TransferablePolicy {
@Override @Override
public boolean accept(Transferable tr) throws Exception { public boolean accept(Transferable tr) throws Exception {
try { try {
List<File> files = getFilesFromTransferable(tr); List<File> files = getFilesFromTransferable(tr);
// ignore temporary files (may not work on all platforms since the DnD data may not be accessible during the drag) // ignore temporary files (may not work on all platforms since the DnD data may not be accessible during the drag)
if (files != null && files.size() > 0 && containsOnly(files, TEMPORARY)) { if (files != null && files.size() > 0 && containsOnly(files, TEMPORARY)) {
return false; return false;
} }
return accept(files); return accept(files);
} catch (UnsupportedFlavorException e) { } catch (UnsupportedFlavorException e) {
// no file list flavor // no file list flavor
} }
return false; return false;
} }
@Override @Override
public void handleTransferable(Transferable tr, TransferAction action) throws Exception { public void handleTransferable(Transferable tr, TransferAction action) throws Exception {
List<File> files = getFilesFromTransferable(tr); List<File> files = getFilesFromTransferable(tr);
if (action == TransferAction.PUT) { if (action == TransferAction.PUT) {
clear(); clear();
} }
load(files); load(files);
} }
protected abstract boolean accept(List<File> files); protected abstract boolean accept(List<File> files);
protected abstract void load(List<File> files) throws IOException; protected abstract void load(List<File> files) throws IOException;
protected abstract void clear(); protected abstract void clear();
public String getFileFilterDescription() { public String getFileFilterDescription() {
return null; return null;
} }
} }