* added persistent rename history

* renamed some setting keys
This commit is contained in:
Reinhard Pointner 2009-05-12 00:17:53 +00:00
parent 049ae3e8ef
commit 63f5f4ba26
9 changed files with 264 additions and 23 deletions

View File

@ -39,8 +39,8 @@
Subdirectories can be specified below the property e.g. java.io.tmpdir/one
-->
<diskStore path="java.io.tmpdir/filebot-ehcache" />
<diskStore path="java.io.tmpdir/filebot-cache" />
<!--
Cache configuration
===================
@ -114,9 +114,7 @@
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
maxElementsOnDisk="1000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
@ -129,6 +127,7 @@
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="300"
overflowToDisk="false"
diskPersistent="false"
memoryStoreEvictionPolicy="LRU"
/>
@ -141,7 +140,8 @@
maxElementsInMemory="4200"
eternal="false"
timeToIdleSeconds="7200"
timeToLiveSeconds="7200"
timeToLiveSeconds="7200"
overflowToDisk="false"
diskPersistent="false"
memoryStoreEvictionPolicy="LRU"
/>

View File

@ -90,7 +90,7 @@ public abstract class AbstractSearchPanel<S, E> extends JComponent {
@Override
public void stateChanged(ChangeEvent e) {
getSettings().put("search", Integer.toString(searchTextField.getSelectButton().getSelectedIndex()));
getSettings().put("engine.selected", Integer.toString(searchTextField.getSelectButton().getSelectedIndex()));
}
});

View File

@ -368,7 +368,7 @@ public class EpisodeFormatDialog extends JDialog {
private void checkFormatInBackground() {
try {
// check syntax in foreground
final ExpressionFormat format = new ExpressionFormat(editor.getText().trim());
final ExpressionFormat format = new ExpressionFormat(getExpression());
// format in background
final Timer progressIndicatorTimer = TunedUtilities.invokeLater(400, new Runnable() {
@ -430,7 +430,7 @@ public class EpisodeFormatDialog extends JDialog {
public String getExpression() {
return editor.getText();
return editor.getText().trim();
}
@ -473,10 +473,10 @@ public class EpisodeFormatDialog extends JDialog {
throw new IllegalStateException("Format has not been verified yet.");
// check syntax
new ExpressionFormat(editor.getText());
ExpressionFormat format = new ExpressionFormat(getExpression());
// remember format
Settings.userRoot().put("dialog.format", editor.getText());
Settings.userRoot().put("dialog.format", format.getExpression());
finish(Option.APPROVE);
} catch (Exception e) {

View File

@ -52,7 +52,7 @@ public class MainFrame extends JFrame {
private HeaderPanel headerPanel = new HeaderPanel();
private final PreferencesEntry<Integer> persistentSelectedPanel = Settings.userRoot().entry("selectedPanel", SimpleAdapter.forClass(Integer.class));
private final PreferencesEntry<Integer> persistentSelectedPanel = Settings.userRoot().entry("panel.selected", SimpleAdapter.forClass(Integer.class));
public MainFrame() {

View File

@ -58,6 +58,7 @@ public class EpisodeListPanel extends AbstractSearchPanel<EpisodeListProvider, E
// add after text field
add(seasonSpinner, 1);
// add after tabbed pane
tabbedPaneGroup.add(new JButton(new SaveAction(new SelectedTabExportHandler())));

View File

@ -0,0 +1,150 @@
package net.sourceforge.filebot.ui.panel.rename;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map.Entry;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "history")
class History {
@XmlElement(name = "sequence")
private List<Sequence> sequences = new ArrayList<Sequence>();
public static class Sequence {
@XmlAttribute(name = "date", required = true)
private Date date;
@XmlElement(name = "rename", required = true)
private List<Element> elements;
private Sequence() {
// hide constructor
}
public Date date() {
return date;
}
public List<Element> elements() {
return elements;
}
}
public static class Element {
@XmlAttribute(name = "dir", required = true)
private File dir;
@XmlAttribute(name = "from", required = true)
private String from;
@XmlAttribute(name = "to", required = true)
private String to;
private Element() {
// hide constructor
}
public File dir() {
return dir;
}
public File from() {
return new File(dir, from);
}
public File to() {
return new File(dir, to);
}
}
public List<Sequence> sequences() {
return Collections.unmodifiableList(sequences);
}
public void add(Iterable<Entry<File, File>> elements) {
Sequence sequence = new Sequence();
sequence.date = new Date();
sequence.elements = new ArrayList<Element>();
for (Entry<File, File> entry : elements) {
File from = entry.getKey();
File to = entry.getValue();
// sanity check, parent folder must be the same for both files
if (!from.getParentFile().equals(to.getParentFile())) {
throw new IllegalArgumentException(String.format("Illegal entry: ", entry));
}
Element element = new Element();
element.dir = from.getParentFile();
element.from = from.getName();
element.to = to.getName();
sequence.elements.add(element);
}
sequences.add(sequence);
}
public void add(History other) {
this.sequences.addAll(other.sequences);
}
public int size() {
return sequences.size();
}
public void clear() {
sequences.clear();
}
public void store(File file) throws JAXBException {
Marshaller marshaller = JAXBContext.newInstance(History.class).createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(this, file);
}
public void load(File file) throws JAXBException {
Unmarshaller unmarshaller = JAXBContext.newInstance(History.class).createUnmarshaller();
History history = ((History) unmarshaller.unmarshal(file));
clear();
add(history);
}
}

View File

@ -0,0 +1,78 @@
package net.sourceforge.filebot.ui.panel.rename;
import java.io.File;
import java.util.Collection;
import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;
final class HistorySpooler {
private static final HistorySpooler instance = new HistorySpooler();
public static HistorySpooler getInstance() {
return instance;
}
private final History sessionHistory = new History();
private final File file = new File("history.xml");
public synchronized History getHistory() {
History history = new History();
// add persistent history
if (file.exists()) {
try {
history.load(file);
} catch (Exception e) {
Logger.getLogger("global").log(Level.SEVERE, "Failed to load history", e);
}
}
// add session history
history.add(sessionHistory);
return history;
}
public synchronized void append(Collection<Entry<File, File>> elements) {
if (elements.isEmpty())
return;
// append to session history
sessionHistory.add(elements);
}
public synchronized void commit() {
if (sessionHistory.size() > 0) {
try {
getHistory().store(file);
// clear session history
sessionHistory.clear();
} catch (Exception e) {
Logger.getLogger("global").log(Level.SEVERE, "Failed to store history", e);
}
}
}
private HistorySpooler() {
// commit session history on shutdown
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
commit();
}
}));
}
}

View File

@ -6,8 +6,8 @@ import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.Map.Entry;
import java.util.logging.Logger;
@ -49,16 +49,21 @@ class RenameAction extends AbstractAction {
// could not rename one of the files, revert all changes
Logger.getLogger("ui").warning(e.getMessage());
// revert in reverse order
Collections.reverse(renameLog);
// revert rename operations
for (Entry<File, File> mapping : renameLog) {
if (!mapping.getValue().renameTo(mapping.getKey())) {
// revert rename operations in reverse order
for (ListIterator<Entry<File, File>> iterator = renameLog.listIterator(renameLog.size()); iterator.hasPrevious();) {
Entry<File, File> mapping = iterator.previous();
if (mapping.getValue().renameTo(mapping.getKey())) {
// remove reverted rename operation from log
iterator.remove();
} else {
// failed to revert rename operation
Logger.getLogger("ui").severe(String.format("Failed to revert file: \"%s\".", mapping.getValue().getName()));
}
}
}
// update history
HistorySpooler.getInstance().append(renameLog);
}
}

View File

@ -50,6 +50,7 @@ import net.sourceforge.filebot.web.TheTVDBClient;
import net.sourceforge.tuned.ExceptionUtilities;
import net.sourceforge.tuned.PreferencesMap.AbstractAdapter;
import net.sourceforge.tuned.PreferencesMap.PreferencesEntry;
import net.sourceforge.tuned.PreferencesMap.SimpleAdapter;
import net.sourceforge.tuned.ui.ActionPopup;
import net.sourceforge.tuned.ui.LoadingOverlayPane;
import ca.odell.glazedlists.ListSelection;
@ -68,6 +69,8 @@ public class RenamePanel extends JComponent {
protected final RenameAction renameAction = new RenameAction(renameModel);
private final PreferencesEntry<Boolean> persistentPreserveExtension = Settings.userRoot().entry("rename.extension.preserve", SimpleAdapter.forClass(Boolean.class));
public RenamePanel() {
namesList.setTitle("New Names");
@ -76,8 +79,13 @@ public class RenamePanel extends JComponent {
filesList.setTitle("Original Files");
filesList.setTransferablePolicy(new FilesListTransferablePolicy(renameModel.files()));
// restore state
renameModel.setPreserveExtension(Boolean.valueOf(Settings.userRoot().get("rename.preserveExtension", "true")));
try {
// restore state
renameModel.setPreserveExtension(persistentPreserveExtension.getValue());
} catch (Exception e) {
// preserve extension by default
renameModel.setPreserveExtension(true);
}
// filename formatter
renameModel.useFormatter(File.class, new FileNameFormatter(renameModel.preserveExtension()));
@ -227,9 +235,8 @@ public class RenamePanel extends JComponent {
filesList.repaint();
// save state
Settings.userRoot().put("rename.preserveExtension", Boolean.toString(activate));
persistentPreserveExtension.setValue(activate);
}
}
@ -340,7 +347,7 @@ public class RenamePanel extends JComponent {
}
}
protected final PreferencesEntry<EpisodeExpressionFormatter> persistentFormatExpression = Settings.userRoot().entry("rename.format", new AbstractAdapter<EpisodeExpressionFormatter>() {
private final PreferencesEntry<EpisodeExpressionFormatter> persistentFormatExpression = Settings.userRoot().entry("rename.format", new AbstractAdapter<EpisodeExpressionFormatter>() {
@Override
public EpisodeExpressionFormatter get(Preferences prefs, String key) {