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/xz.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/groovy-all.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.IOException;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.attribute.BasicFileAttributes;
import net.filebot.util.FileUtilities;
@ -128,8 +130,43 @@ public enum StandardRenameAction implements RenameAction {
if (it.name().equalsIgnoreCase(action))
return it;
}
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.Settings.*;
import static net.filebot.UserFiles.*;
import static net.filebot.util.FileUtilities.*;
import static net.filebot.util.ui.SwingUI.*;
import java.awt.Color;
@ -72,7 +71,7 @@ import net.filebot.History;
import net.filebot.History.Element;
import net.filebot.History.Sequence;
import net.filebot.ResourceManager;
import net.filebot.Settings;
import net.filebot.StandardRenameAction;
import net.filebot.mac.MacAppUtilities;
import net.filebot.media.MetaAttributes;
import net.filebot.ui.transfer.FileExportHandler;
@ -445,25 +444,15 @@ class HistoryDialog extends JDialog {
}
private enum Option {
Rename {
Revert, ChangeDirectory, Cancel;
@Override
public String toString() {
return "Rename";
}
},
ChangeDirectory {
@Override
public String toString() {
@Override
public String toString() {
switch (this) {
case ChangeDirectory:
return "Change Directory";
}
},
Cancel {
@Override
public String toString() {
return "Cancel";
default:
return name();
}
}
}
@ -488,9 +477,9 @@ class HistoryDialog extends JDialog {
Set<Option> options;
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;
options = EnumSet.of(Option.Rename, Option.ChangeDirectory, Option.Cancel);
options = EnumSet.of(Option.Revert, Option.ChangeDirectory, Option.Cancel);
} else {
String text = "Some files are missing. Please select a different directory.";
JList missingFilesComponent = new JList(missingFiles.toArray()) {
@ -530,12 +519,12 @@ class HistoryDialog extends JDialog {
}
// rename files
if (selectedOption == Option.Rename) {
rename(directory, elements);
if (selectedOption == Option.Revert) {
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);
if (isMacSandbox()) {
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;
for (Entry<File, File> entry : renamePlan.entrySet()) {
try {
File destination = moveRename(entry.getKey(), entry.getValue());
try {
for (Entry<File, File> entry : renamePlan.entrySet()) {
File original = StandardRenameAction.revert(entry.getKey(), entry.getValue());
count++;
// remove xattr that may have been set
if (Settings.useExtendedFileAttributes()) {
new MetaAttributes(destination).clear();
if (original.isFile() && useExtendedFileAttributes()) {
new MetaAttributes(original).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();
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"));
} 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"));
}