+ support all rename actions (move, copy, hardlink, ...) in GUI as well

+ include/exclude extension mode evolved to Relative Name / Absolute Path modes
This commit is contained in:
Reinhard Pointner 2012-07-12 11:23:23 +00:00
parent 44bd9e2480
commit 6631740d98
15 changed files with 119 additions and 51 deletions

View File

@ -1,5 +1,5 @@
package net.sourceforge.filebot.cli; package net.sourceforge.filebot;
import java.io.File; import java.io.File;

View File

@ -1,5 +1,5 @@
package net.sourceforge.filebot.cli; package net.sourceforge.filebot;
import java.io.File; import java.io.File;

View File

@ -46,6 +46,8 @@ import java.util.regex.Pattern;
import net.sourceforge.filebot.Analytics; import net.sourceforge.filebot.Analytics;
import net.sourceforge.filebot.HistorySpooler; import net.sourceforge.filebot.HistorySpooler;
import net.sourceforge.filebot.MediaTypes; import net.sourceforge.filebot.MediaTypes;
import net.sourceforge.filebot.RenameAction;
import net.sourceforge.filebot.StandardRenameAction;
import net.sourceforge.filebot.WebServices; import net.sourceforge.filebot.WebServices;
import net.sourceforge.filebot.archive.Archive; import net.sourceforge.filebot.archive.Archive;
import net.sourceforge.filebot.archive.FileMapper; import net.sourceforge.filebot.archive.FileMapper;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 947 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 679 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 655 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 883 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 B

View File

@ -11,7 +11,7 @@ import net.sourceforge.tuned.FileUtilities;
class FileNameFormatter implements MatchFormatter { class FileNameFormatter implements MatchFormatter {
private final boolean preserveExtension; private boolean preserveExtension;
public FileNameFormatter(boolean preserveExtension) { public FileNameFormatter(boolean preserveExtension) {
@ -21,7 +21,7 @@ class FileNameFormatter implements MatchFormatter {
@Override @Override
public boolean canFormat(Match<?, ?> match) { public boolean canFormat(Match<?, ?> match) {
return match.getValue() instanceof File || match.getValue() instanceof FileInfo; return match.getValue() instanceof File || match.getValue() instanceof FileInfo || match.getValue() instanceof String;
} }
@ -33,18 +33,24 @@ class FileNameFormatter implements MatchFormatter {
@Override @Override
public String format(Match<?, ?> match) { public String format(Match<?, ?> match) {
if (match.getValue() instanceof File) { Object value = match.getValue();
File file = (File) match.getValue();
if (value instanceof File) {
File file = (File) value;
return preserveExtension ? FileUtilities.getName(file) : file.getName(); return preserveExtension ? FileUtilities.getName(file) : file.getName();
} }
if (match.getValue() instanceof FileInfo) { if (value instanceof FileInfo) {
FileInfo file = (FileInfo) match.getValue(); FileInfo file = (FileInfo) value;
return preserveExtension ? file.getName() : file.getPath(); return preserveExtension ? file.getName() : file.getPath();
} }
if (value instanceof String) {
return preserveExtension ? FileUtilities.getNameWithoutExtension(value.toString()) : value.toString();
}
// cannot format value // cannot format value
throw new IllegalArgumentException("Illegal value: " + match.getValue()); throw new IllegalArgumentException("Illegal value: " + value);
} }
} }

View File

@ -4,7 +4,6 @@ package net.sourceforge.filebot.ui.rename;
import static java.util.Collections.*; import static java.util.Collections.*;
import static net.sourceforge.filebot.ui.NotificationLogging.*; import static net.sourceforge.filebot.ui.NotificationLogging.*;
import static net.sourceforge.tuned.FileUtilities.*;
import static net.sourceforge.tuned.ui.TunedUtilities.*; import static net.sourceforge.tuned.ui.TunedUtilities.*;
import java.awt.Cursor; import java.awt.Cursor;
@ -33,6 +32,7 @@ import javax.swing.SwingWorker;
import net.sourceforge.filebot.Analytics; import net.sourceforge.filebot.Analytics;
import net.sourceforge.filebot.HistorySpooler; import net.sourceforge.filebot.HistorySpooler;
import net.sourceforge.filebot.ResourceManager; import net.sourceforge.filebot.ResourceManager;
import net.sourceforge.filebot.StandardRenameAction;
import net.sourceforge.tuned.ui.ProgressDialog; import net.sourceforge.tuned.ui.ProgressDialog;
import net.sourceforge.tuned.ui.ProgressDialog.Cancellable; import net.sourceforge.tuned.ui.ProgressDialog.Cancellable;
import net.sourceforge.tuned.ui.SwingWorkerPropertyChangeAdapter; import net.sourceforge.tuned.ui.SwingWorkerPropertyChangeAdapter;
@ -40,15 +40,21 @@ import net.sourceforge.tuned.ui.SwingWorkerPropertyChangeAdapter;
class RenameAction extends AbstractAction { class RenameAction extends AbstractAction {
public static final String RENAME_ACTION = "RENAME_ACTION";
private final RenameModel model; private final RenameModel model;
public RenameAction(RenameModel model) { public RenameAction(RenameModel model) {
this.model = model; this.model = model;
resetValues();
}
public void resetValues() {
putValue(RENAME_ACTION, StandardRenameAction.MOVE);
putValue(NAME, "Rename"); putValue(NAME, "Rename");
putValue(SMALL_ICON, ResourceManager.getIcon("action.rename")); putValue(SMALL_ICON, ResourceManager.getIcon("action.rename"));
putValue(SHORT_DESCRIPTION, "Rename files");
} }
@ -62,7 +68,7 @@ class RenameAction extends AbstractAction {
Map<File, File> renameMap = checkRenamePlan(validate(model.getRenameMap(), window)); Map<File, File> renameMap = checkRenamePlan(validate(model.getRenameMap(), window));
window.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); window.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
RenameJob renameJob = new RenameJob(renameMap); RenameJob renameJob = new RenameJob(renameMap, (StandardRenameAction) getValue(RENAME_ACTION));
renameJob.execute(); renameJob.execute();
try { try {
@ -192,11 +198,14 @@ class RenameAction extends AbstractAction {
protected class RenameJob extends SwingWorker<Map<File, File>, Void> implements Cancellable { protected class RenameJob extends SwingWorker<Map<File, File>, Void> implements Cancellable {
private final StandardRenameAction action;
private final Map<File, File> renameMap; private final Map<File, File> renameMap;
private final Map<File, File> renameLog; private final Map<File, File> renameLog;
public RenameJob(Map<File, File> renameMap) { public RenameJob(Map<File, File> renameMap, StandardRenameAction action) {
this.action = action;
this.renameMap = synchronizedMap(renameMap); this.renameMap = synchronizedMap(renameMap);
this.renameLog = synchronizedMap(new LinkedHashMap<File, File>()); this.renameLog = synchronizedMap(new LinkedHashMap<File, File>());
} }
@ -213,7 +222,7 @@ class RenameAction extends AbstractAction {
firePropertyChange("currentFile", mapping.getKey(), mapping.getValue()); firePropertyChange("currentFile", mapping.getKey(), mapping.getValue());
// rename file, throw exception on failure // rename file, throw exception on failure
moveRename(mapping.getKey(), mapping.getValue()); action.rename(mapping.getKey(), mapping.getValue());
// remember successfully renamed matches for history entry and possible revert // remember successfully renamed matches for history entry and possible revert
renameLog.put(mapping.getKey(), mapping.getValue()); renameLog.put(mapping.getKey(), mapping.getValue());

View File

@ -89,12 +89,20 @@ class RenameListCellRenderer extends DefaultFancyListCellRenderer {
if (renameModel.preserveExtension()) { if (renameModel.preserveExtension()) {
setText(FileUtilities.getName(file)); setText(FileUtilities.getName(file));
} else { } else {
setText(file.getName()); setText(file.getAbsolutePath());
} }
} else if (value instanceof FormattedFuture) { } else if (value instanceof FormattedFuture) {
// display progress icon // display progress icon
FormattedFuture formattedFuture = (FormattedFuture) value; FormattedFuture formattedFuture = (FormattedFuture) value;
if (!renameModel.preserveExtension() && formattedFuture.isDone() && renameModel.hasComplement(index)) {
// absolute path mode
File targetDir = renameModel.getMatch(index).getCandidate().getParentFile();
setText(resolveAbsolutePath(targetDir, formattedFuture.toString()));
} else {
// relative name mode
setText(formattedFuture.isDone() && !formattedFuture.isCancelled() ? formattedFuture.toString() : formattedFuture.preview()); setText(formattedFuture.isDone() && !formattedFuture.isCancelled() ? formattedFuture.toString() : formattedFuture.preview());
}
switch (formattedFuture.getState()) { switch (formattedFuture.getState()) {
case PENDING: case PENDING:
@ -128,6 +136,20 @@ class RenameListCellRenderer extends DefaultFancyListCellRenderer {
} }
protected String resolveAbsolutePath(File targetDir, String path) {
File f = new File(path);
if (!f.isAbsolute()) {
f = new File(targetDir, path); // resolve path against target folder
}
try {
return f.getCanonicalPath();
} catch (Exception e) {
return f.getAbsolutePath();
}
}
protected float getMatchProbablity(Match<Object, File> match) { protected float getMatchProbablity(Match<Object, File> match) {
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());

View File

@ -16,6 +16,7 @@ import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.EnumSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -46,6 +47,7 @@ import net.sourceforge.filebot.History;
import net.sourceforge.filebot.HistorySpooler; import net.sourceforge.filebot.HistorySpooler;
import net.sourceforge.filebot.ResourceManager; import net.sourceforge.filebot.ResourceManager;
import net.sourceforge.filebot.Settings; import net.sourceforge.filebot.Settings;
import net.sourceforge.filebot.StandardRenameAction;
import net.sourceforge.filebot.WebServices; import net.sourceforge.filebot.WebServices;
import net.sourceforge.filebot.similarity.Match; import net.sourceforge.filebot.similarity.Match;
import net.sourceforge.filebot.ui.Language; import net.sourceforge.filebot.ui.Language;
@ -153,13 +155,19 @@ public class RenamePanel extends JComponent {
} }
}); });
// create settings popup namesList.getListComponent().setComponentPopupMenu(fetchPopup);
final Action settingsPopupAction = new ShowPopupAction("Options", ResourceManager.getIcon("action.report")); fetchButton.setComponentPopupMenu(fetchPopup);
JButton settingsButton = createImageButton(settingsPopupAction);
settingsButton.setAction(openHistoryAction); // settings popup and button
ActionPopup settingsPopup = createSettingsPopup(); ActionPopup settingsPopup = createSettingsPopup();
final Action settingsPopupAction = new ShowPopupAction("Settings", ResourceManager.getIcon("action.settings"));
JButton settingsButton = createImageButton(settingsPopupAction);
settingsButton.setComponentPopupMenu(settingsPopup);
renameButton.setComponentPopupMenu(settingsPopup); renameButton.setComponentPopupMenu(settingsPopup);
filesList.getButtonPanel().add(settingsButton, "gap 0"); namesList.getButtonPanel().add(settingsButton, "gap indent");
// open rename log button
filesList.getButtonPanel().add(createImageButton(openHistoryAction), "gap 0");
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%"));
@ -276,16 +284,18 @@ public class RenamePanel extends JComponent {
protected ActionPopup createSettingsPopup() { protected ActionPopup createSettingsPopup() {
ActionPopup actionPopup = new ActionPopup("Rename Options", ResourceManager.getIcon("action.rename.small")); ActionPopup actionPopup = new ActionPopup("Rename Options", ResourceManager.getIcon("action.settings"));
actionPopup.addDescription(new JLabel("Extension:")); actionPopup.addDescription(new JLabel("Mode:"));
actionPopup.add(new SetRenameMode(false, "Relative Name", ResourceManager.getIcon("action.extension.preserve")));
actionPopup.add(new OverrideExtensionAction(false, "Preserve", ResourceManager.getIcon("action.extension.preserve"))); actionPopup.add(new SetRenameMode(true, "Absolute Path", ResourceManager.getIcon("action.extension.override")));
actionPopup.add(new OverrideExtensionAction(true, "Override", ResourceManager.getIcon("action.extension.override")));
actionPopup.addSeparator(); actionPopup.addSeparator();
actionPopup.addDescription(new JLabel("History:"));
actionPopup.add(openHistoryAction); actionPopup.addDescription(new JLabel("Action:"));
for (StandardRenameAction action : EnumSet.of(StandardRenameAction.MOVE, StandardRenameAction.COPY, StandardRenameAction.KEEPLINK, StandardRenameAction.SYMLINK, StandardRenameAction.HARDLINK)) {
actionPopup.add(new SetRenameAction(action, action.toString().toLowerCase(), ResourceManager.getIcon("rename.action." + action.toString().toLowerCase())));
}
return actionPopup; return actionPopup;
} }
@ -328,12 +338,12 @@ public class RenamePanel extends JComponent {
}; };
protected class OverrideExtensionAction extends AbstractAction { protected class SetRenameMode extends AbstractAction {
private final boolean activate; private final boolean activate;
private OverrideExtensionAction(boolean activate, String name, Icon icon) { private SetRenameMode(boolean activate, String name, Icon icon) {
super(name, icon); super(name, icon);
this.activate = activate; this.activate = activate;
} }
@ -352,6 +362,26 @@ public class RenamePanel extends JComponent {
} }
protected class SetRenameAction extends AbstractAction {
private final StandardRenameAction action;
public SetRenameAction(StandardRenameAction action, String name, Icon icon) {
super(name, icon);
this.action = action;
}
@Override
public void actionPerformed(ActionEvent evt) {
renameAction.putValue(RenameAction.RENAME_ACTION, action);
renameAction.putValue(NAME, this.getValue(NAME));
renameAction.putValue(SMALL_ICON, this.getValue(SMALL_ICON));
}
}
protected class AutoCompleteAction extends AbstractAction { protected class AutoCompleteAction extends AbstractAction {
private final AutoCompleteMatcher matcher; private final AutoCompleteMatcher matcher;

View File

@ -67,18 +67,17 @@ public class ActionPopup extends JPopupMenu {
public JMenuItem add(Action a) { public JMenuItem add(Action a) {
LinkButton link = new LinkButton(a); LinkButton link = new LinkButton(a);
// close popup when action is triggered
link.addActionListener(closeListener);
// underline text // underline text
link.setText(String.format("<html><u>%s</u></html>", link.getText())); link.setText(String.format("<html><nobr><u>%s</u></nobr></html>", link.getText()));
// use rollover color // use rollover color
link.setRolloverEnabled(false); link.setRolloverEnabled(false);
link.setColor(link.getRolloverColor()); link.setColor(link.getRolloverColor());
addAction(link); // close popup when action is triggered
link.addActionListener(closeListener);
addAction(link);
return null; return null;
} }