* support dropping of large / slow folders into Rename panel (Files list)
This commit is contained in:
parent
124e7471db
commit
98633f7364
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue