Support REVERT for all rename actions

This commit is contained in:
Reinhard Pointner 2016-03-10 16:23:45 +00:00
parent 4d695a1d7d
commit 9f9aa9ed82
3 changed files with 61 additions and 36 deletions

View File

@ -17,7 +17,7 @@
<classpathentry kind="lib" path="lib/ivy/jar/rsyntaxtextarea.jar"/> <classpathentry kind="lib" path="lib/ivy/jar/rsyntaxtextarea.jar"/>
<classpathentry kind="lib" path="lib/ivy/jar/xz.jar"/> <classpathentry kind="lib" path="lib/ivy/jar/xz.jar"/>
<classpathentry kind="lib" path="lib/ivy/jar/slf4j-api.jar"/> <classpathentry kind="lib" path="lib/ivy/jar/slf4j-api.jar"/>
<classpathentry kind="lib" path="lib/ivy/jar/commons-io.jar"/> <classpathentry kind="lib" path="lib/ivy/jar/commons-io.jar" sourcepath="lib/ivy/source/commons-io.jar"/>
<classpathentry kind="lib" path="lib/ivy/jar/jsoup.jar"/> <classpathentry kind="lib" path="lib/ivy/jar/jsoup.jar"/>
<classpathentry kind="lib" path="lib/ivy/jar/groovy-all.jar"/> <classpathentry kind="lib" path="lib/ivy/jar/groovy-all.jar"/>
<classpathentry kind="lib" path="lib/ivy/jar/slf4j-jdk14.jar"/> <classpathentry kind="lib" path="lib/ivy/jar/slf4j-jdk14.jar"/>

View File

@ -3,6 +3,8 @@ package net.filebot;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.attribute.BasicFileAttributes;
import net.filebot.util.FileUtilities; import net.filebot.util.FileUtilities;
@ -128,8 +130,43 @@ public enum StandardRenameAction implements RenameAction {
if (it.name().equalsIgnoreCase(action)) if (it.name().equalsIgnoreCase(action))
return it; return it;
} }
throw new IllegalArgumentException("Illegal rename action: " + action); throw new IllegalArgumentException("Illegal rename action: " + action);
} }
public static File revert(File current, File original) throws IOException {
// reverse move
if (current.exists() && !original.exists()) {
return FileUtilities.moveRename(current, original);
}
BasicFileAttributes currentAttr = Files.readAttributes(current.toPath(), BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);
BasicFileAttributes originalAttr = Files.readAttributes(original.toPath(), BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);
// reverse symlink
if (currentAttr.isSymbolicLink() && !originalAttr.isSymbolicLink()) {
Files.delete(current.toPath());
return original;
}
// reverse keeplink
if (!currentAttr.isSymbolicLink() && originalAttr.isSymbolicLink()) {
Files.delete(original.toPath());
return FileUtilities.moveRename(current, original);
}
// reverse copy / hardlink
if (currentAttr.isRegularFile() && originalAttr.isRegularFile()) {
Files.delete(current.toPath());
return original;
}
// reverse folder copy
if (currentAttr.isDirectory() && originalAttr.isDirectory()) {
FileUtilities.delete(original);
return FileUtilities.moveRename(current, original);
}
throw new IllegalArgumentException(String.format("Cannot revert files: %s => %s", current, original));
}
} }

View File

@ -8,7 +8,6 @@ import static javax.swing.JOptionPane.*;
import static net.filebot.Logging.*; import static net.filebot.Logging.*;
import static net.filebot.Settings.*; import static net.filebot.Settings.*;
import static net.filebot.UserFiles.*; import static net.filebot.UserFiles.*;
import static net.filebot.util.FileUtilities.*;
import static net.filebot.util.ui.SwingUI.*; import static net.filebot.util.ui.SwingUI.*;
import java.awt.Color; import java.awt.Color;
@ -72,7 +71,7 @@ import net.filebot.History;
import net.filebot.History.Element; import net.filebot.History.Element;
import net.filebot.History.Sequence; import net.filebot.History.Sequence;
import net.filebot.ResourceManager; import net.filebot.ResourceManager;
import net.filebot.Settings; import net.filebot.StandardRenameAction;
import net.filebot.mac.MacAppUtilities; import net.filebot.mac.MacAppUtilities;
import net.filebot.media.MetaAttributes; import net.filebot.media.MetaAttributes;
import net.filebot.ui.transfer.FileExportHandler; import net.filebot.ui.transfer.FileExportHandler;
@ -445,25 +444,15 @@ class HistoryDialog extends JDialog {
} }
private enum Option { private enum Option {
Rename { Revert, ChangeDirectory, Cancel;
@Override @Override
public String toString() { public String toString() {
return "Rename"; switch (this) {
} case ChangeDirectory:
},
ChangeDirectory {
@Override
public String toString() {
return "Change Directory"; return "Change Directory";
} default:
}, return name();
Cancel {
@Override
public String toString() {
return "Cancel";
} }
} }
} }
@ -488,9 +477,9 @@ class HistoryDialog extends JDialog {
Set<Option> options; Set<Option> options;
if (missingFiles.isEmpty()) { if (missingFiles.isEmpty()) {
message = String.format("Are you sure you want to rename %d file(s)?", elements.size()); message = String.format("Are you sure you want to revert %d file(s)?", elements.size());
type = QUESTION_MESSAGE; type = QUESTION_MESSAGE;
options = EnumSet.of(Option.Rename, Option.ChangeDirectory, Option.Cancel); options = EnumSet.of(Option.Revert, Option.ChangeDirectory, Option.Cancel);
} else { } else {
String text = "Some files are missing. Please select a different directory."; String text = "Some files are missing. Please select a different directory.";
JList missingFilesComponent = new JList(missingFiles.toArray()) { JList missingFilesComponent = new JList(missingFiles.toArray()) {
@ -530,12 +519,12 @@ class HistoryDialog extends JDialog {
} }
// rename files // rename files
if (selectedOption == Option.Rename) { if (selectedOption == Option.Revert) {
rename(directory, elements); revert(directory, elements);
} }
} }
private void rename(File directory, List<Element> elements) { private void revert(File directory, List<Element> elements) {
Map<File, File> renamePlan = getRenameMap(directory); Map<File, File> renamePlan = getRenameMap(directory);
if (isMacSandbox()) { if (isMacSandbox()) {
if (!MacAppUtilities.askUnlockFolders(parent(), Stream.of(renamePlan.keySet(), renamePlan.values()).flatMap(c -> c.stream()).collect(Collectors.toList()))) { if (!MacAppUtilities.askUnlockFolders(parent(), Stream.of(renamePlan.keySet(), renamePlan.values()).flatMap(c -> c.stream()).collect(Collectors.toList()))) {
@ -544,26 +533,25 @@ class HistoryDialog extends JDialog {
} }
int count = 0; int count = 0;
for (Entry<File, File> entry : renamePlan.entrySet()) { try {
try { for (Entry<File, File> entry : renamePlan.entrySet()) {
File destination = moveRename(entry.getKey(), entry.getValue()); File original = StandardRenameAction.revert(entry.getKey(), entry.getValue());
count++; count++;
// remove xattr that may have been set if (original.isFile() && useExtendedFileAttributes()) {
if (Settings.useExtendedFileAttributes()) { new MetaAttributes(original).clear();
new MetaAttributes(destination).clear();
} }
} catch (Exception e) {
debug.log(Level.SEVERE, e.getMessage(), e);
} }
} catch (Exception e) {
log.log(Level.WARNING, "Failed to revert files: " + e.getMessage(), e);
} }
JLabel status = parent().getInfoLabel(); JLabel status = parent().getInfoLabel();
if (count == elements.size()) { if (count == elements.size()) {
status.setText(String.format("%d file(s) have been renamed.", count)); status.setText(String.format("%d file(s) have been reverted.", count));
status.setIcon(ResourceManager.getIcon("status.ok")); status.setIcon(ResourceManager.getIcon("status.ok"));
} else { } else {
status.setText(String.format("Failed to revert %d file(s).", elements.size() - count, elements.size())); status.setText(String.format("%d of %d file(s) have been reverted.", count, elements.size()));
status.setIcon(ResourceManager.getIcon("status.error")); status.setIcon(ResourceManager.getIcon("status.error"));
} }