Lots of refactoring:

* Removed TransferablePolicySupport and related refactoring
* OpenSubtitlesClient: ignore logout status code
* Animated-GIF are animated again
* Unrar process will not hang anymore
* Improved Subscene scraper
* Better scaling for ProgressIndicator
* Added \r and \n to invalid characters
* Some work on SubtitlePanel and related stuff
* Setting putMap/List methods clear existing data first
This commit is contained in:
Reinhard Pointner 2008-06-02 19:12:28 +00:00
parent 12d453eff4
commit 30a54c2cf4
64 changed files with 742 additions and 599 deletions
build.xml
source/net/sourceforge
filebot
tuned

View File

@ -15,10 +15,16 @@
<property name="lib.nekohtml" value="nekohtml-1.9.7.jar" /> <property name="lib.nekohtml" value="nekohtml-1.9.7.jar" />
<property name="lib.simmetrics" value="simmetrics_jar_v1_6_2_d07_02_07.jar" /> <property name="lib.simmetrics" value="simmetrics_jar_v1_6_2_d07_02_07.jar" />
<property name="lib.xmlrpc" value="xmlrpc-client-1.1.jar" /> <property name="lib.xmlrpc" value="xmlrpc-client-1.1.jar" />
<patternset id="classes">
<include name="**/*.class" />
<include name="**/*.properties" />
<exclude name="**/*Test*" />
</patternset>
<target name="jar" depends="build"> <target name="fatjar" depends="build">
<jar destfile="${executable}" duplicate="fail"> <jar destfile="${executable}" duplicate="fail">
<fileset dir="${build}" /> <fileset dir="${build}" />
@ -28,38 +34,27 @@
<attribute name="Version" value="${version}" /> <attribute name="Version" value="${version}" />
</manifest> </manifest>
<!-- include libs if fatjar is set --> <!-- include libs if fatjar is set -->
<zipfileset src="${lib}/${lib.xerces}"> <zipfileset src="${lib}/${lib.xerces}">
<include if="fatjar" name="**/*.class" /> <patternset refid="classes" />
<include if="fatjar" name="**/*.properties" />
<exclude if="fatjar" name="**/*Test*" />
</zipfileset> </zipfileset>
<zipfileset src="${lib}/${lib.nekohtml}"> <zipfileset src="${lib}/${lib.nekohtml}">
<include if="fatjar" name="**/*.class" /> <patternset refid="classes" />
<include if="fatjar" name="**/*.properties" />
<exclude if="fatjar" name="**/*Test*" />
</zipfileset> </zipfileset>
<zipfileset src="${lib}/${lib.simmetrics}"> <zipfileset src="${lib}/${lib.simmetrics}">
<include if="fatjar" name="**/*.class" /> <patternset refid="classes" />
<include if="fatjar" name="**/*.properties" />
<exclude if="fatjar" name="**/*Test*" />
</zipfileset> </zipfileset>
<zipfileset src="${lib}/${lib.xmlrpc}"> <zipfileset src="${lib}/${lib.xmlrpc}">
<include if="fatjar" name="**/*.class" /> <patternset refid="classes" />
<include if="fatjar" name="**/*.properties" />
<exclude if="fatjar" name="**/*Test*" />
</zipfileset> </zipfileset>
</jar> </jar>
</target> </target>
<target name="fatjar">
<antcall target="jar">
<param name="fatjar" value="true" />
</antcall>
</target>
<target name="build" depends="clean"> <target name="build" depends="clean">
<!-- create build dir --> <!-- create build dir -->
<mkdir dir="${build}" /> <mkdir dir="${build}" />

View File

@ -4,7 +4,11 @@ package net.sourceforge.filebot;
import java.io.File; import java.io.File;
import java.io.FileFilter; import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.FilenameFilter; import java.io.FilenameFilter;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.List; import java.util.List;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -16,9 +20,9 @@ public class FileBotUtil {
} }
/** /**
* invalid characters: \, /, :, *, ?, ", <, > and | * invalid characters: \, /, :, *, ?, ", <, >, |, \r and \n
*/ */
public static final String INVALID_CHARACTERS = "\\/:*?\"<>|"; public static final String INVALID_CHARACTERS = "\\/:*?\"<>|\r\n";
public static final Pattern INVALID_CHARACTERS_PATTERN = Pattern.compile(String.format("[%s]+", Pattern.quote(INVALID_CHARACTERS))); public static final Pattern INVALID_CHARACTERS_PATTERN = Pattern.compile(String.format("[%s]+", Pattern.quote(INVALID_CHARACTERS)));
@ -114,4 +118,12 @@ public class FileBotUtil {
}; };
//TODO needed??
public static void writeToFile(File file, ByteBuffer data) throws IOException {
FileChannel channel = new FileOutputStream(file).getChannel();
channel.write(data);
channel.close();
}
} }

View File

@ -26,14 +26,14 @@ public class Settings {
public static final String SUBTITLE_HISTORY = "subtitle/history"; public static final String SUBTITLE_HISTORY = "subtitle/history";
public static final String SUBTITLE_LANGUAGE = "subtitle/language"; public static final String SUBTITLE_LANGUAGE = "subtitle/language";
private static Settings settings = new Settings(); private static final Settings settings = new Settings();
public static Settings getSettings() { public static Settings getSettings() {
return settings; return settings;
} }
private Preferences prefs; private final Preferences prefs;
private Settings() { private Settings() {
@ -89,7 +89,7 @@ public class Settings {
public void putStringList(String key, Collection<String> list) { public void putStringList(String key, Collection<String> list) {
Preferences listNode = prefs.node(key); Preferences listNode = getClearNode(key);
int i = 0; int i = 0;
@ -118,7 +118,7 @@ public class Settings {
public void putStringMap(String key, Map<String, String> map) { public void putStringMap(String key, Map<String, String> map) {
Preferences mapNode = prefs.node(key); Preferences mapNode = getClearNode(key);
for (Map.Entry<String, String> entry : map.entrySet()) { for (Map.Entry<String, String> entry : map.entrySet()) {
mapNode.put(entry.getKey(), entry.getValue()); mapNode.put(entry.getKey(), entry.getValue());
@ -185,10 +185,24 @@ public class Settings {
public void clear() { public void clear() {
try { try {
prefs.removeNode(); for (String child : prefs.childrenNames()) {
prefs = Preferences.userRoot().node(ROOT); prefs.node(child).removeNode();
}
} catch (BackingStoreException e) { } catch (BackingStoreException e) {
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e); Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
} }
} }
private Preferences getClearNode(String nodeName) {
Preferences node = prefs.node(nodeName);
try {
node.clear();
} catch (BackingStoreException e) {
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
}
return node;
}
} }

View File

@ -9,8 +9,6 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
@ -30,59 +28,47 @@ public class ResourceManager {
aliasMap.put("loading", "loading.gif"); aliasMap.put("loading", "loading.gif");
} }
private static final Map<String, Image> cache = Collections.synchronizedMap(new WeakHashMap<String, Image>()); private static final Map<String, ImageIcon> iconCache = Collections.synchronizedMap(new WeakHashMap<String, ImageIcon>());
public static ImageIcon getIcon(String name) { public static ImageIcon getIcon(String name) {
return new ImageIcon(getImage(name)); return getIcon(name, null);
}
public static ImageIcon getIcon(String name, String def) {
ImageIcon icon = iconCache.get(name);
if (icon == null) {
// load image if not in cache
URL resource = getResource(name, def);
if (resource != null) {
icon = new ImageIcon(resource);
iconCache.put(name, icon);
}
}
return icon;
} }
public static ImageIcon getFlagIcon(String languageCode) { public static ImageIcon getFlagIcon(String languageCode) {
if (languageCode == null) return getIcon(String.format("flags/%s", languageCode), "flags/default");
languageCode = "default";
return new ImageIcon(getImage(String.format("flags/%s", languageCode.toLowerCase()), "flags/default"));
} }
public static ImageIcon getArchiveIcon(String type) { public static ImageIcon getArchiveIcon(String type) {
if (type == null) return getIcon(String.format("archives/%s", type), "archives/default");
type = "default";
return new ImageIcon(getImage(String.format("archives/%s", type.toLowerCase()), "archives/default"));
} }
public static Image getImage(String name) { public static Image getImage(String name) {
Image image = cache.get(name); try {
return ImageIO.read(getResource(name));
if (image == null) { } catch (IOException e) {
try { throw new RuntimeException(e);
// load image if not in cache
URL resource = getResource(name);
if (resource != null) {
image = ImageIO.read(resource);
cache.put(name, image);
}
} catch (IOException e) {
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
}
} }
return image;
}
private static Image getImage(String name, String def) {
Image image = getImage(name);
// image not found, use default
if (image == null)
image = getImage(def);
return image;
} }
@ -97,4 +83,14 @@ public class ResourceManager {
return ResourceManager.class.getResource(resource); return ResourceManager.class.getResource(resource);
} }
private static URL getResource(String name, String def) {
URL resource = getResource(name);
if (resource == null)
resource = getResource(def);
return resource;
}
} }

View File

@ -22,35 +22,28 @@ import javax.swing.border.TitledBorder;
import net.sourceforge.filebot.ui.transfer.DefaultTransferHandler; import net.sourceforge.filebot.ui.transfer.DefaultTransferHandler;
import net.sourceforge.filebot.ui.transfer.ExportHandler; import net.sourceforge.filebot.ui.transfer.ExportHandler;
import net.sourceforge.filebot.ui.transfer.FileTransferable; import net.sourceforge.filebot.ui.transfer.FileTransferable;
import net.sourceforge.filebot.ui.transfer.ImportHandler;
import net.sourceforge.filebot.ui.transfer.Saveable; import net.sourceforge.filebot.ui.transfer.Saveable;
import net.sourceforge.filebot.ui.transfer.SaveableExportHandler; import net.sourceforge.filebot.ui.transfer.SaveableExportHandler;
import net.sourceforge.filebot.ui.transfer.TransferablePolicyImportHandler; import net.sourceforge.filebot.ui.transfer.TransferablePolicyImportHandler;
import net.sourceforge.filebot.ui.transfer.TransferablePolicySupport; import net.sourceforge.filebot.ui.transferablepolicies.MutableTransferablePolicy;
import net.sourceforge.filebot.ui.transferablepolicies.NullTransferablePolicy;
import net.sourceforge.filebot.ui.transferablepolicies.TransferablePolicy; import net.sourceforge.filebot.ui.transferablepolicies.TransferablePolicy;
import net.sourceforge.tuned.ui.DefaultFancyListCellRenderer; import net.sourceforge.tuned.ui.DefaultFancyListCellRenderer;
import net.sourceforge.tuned.ui.SimpleListModel; import net.sourceforge.tuned.ui.SimpleListModel;
import net.sourceforge.tuned.ui.TunedUtil; import net.sourceforge.tuned.ui.TunedUtil;
public class FileBotList extends JPanel implements Saveable, TransferablePolicySupport { public class FileBotList extends JPanel implements Saveable {
private JList list = new JList(new SimpleListModel()); private final JList list = new JList(new SimpleListModel());
private TitledBorder titledBorder; private final MutableTransferablePolicy mutableTransferablePolicy = new MutableTransferablePolicy();
private final TitledBorder titledBorder;
private String title; private String title;
private TransferablePolicy transferablePolicy = new NullTransferablePolicy();
public FileBotList(boolean enableExport, boolean enableRemoveAction, boolean border) {
public FileBotList(boolean enableDrop, boolean enableDrag, boolean enableRemoveAction) {
this(enableDrop, enableDrag, enableRemoveAction, true);
}
public FileBotList(boolean enableImport, boolean enableExport, boolean enableRemoveAction, boolean border) {
super(new BorderLayout()); super(new BorderLayout());
JScrollPane listScrollPane = new JScrollPane(list); JScrollPane listScrollPane = new JScrollPane(list);
@ -59,6 +52,7 @@ public class FileBotList extends JPanel implements Saveable, TransferablePolicyS
titledBorder = new TitledBorder(""); titledBorder = new TitledBorder("");
setBorder(titledBorder); setBorder(titledBorder);
} else { } else {
titledBorder = null;
listScrollPane.setBorder(BorderFactory.createEmptyBorder()); listScrollPane.setBorder(BorderFactory.createEmptyBorder());
} }
@ -67,16 +61,12 @@ public class FileBotList extends JPanel implements Saveable, TransferablePolicyS
add(listScrollPane, BorderLayout.CENTER); add(listScrollPane, BorderLayout.CENTER);
ImportHandler importHander = null;
ExportHandler exportHandler = null; ExportHandler exportHandler = null;
if (enableImport)
importHander = new TransferablePolicyImportHandler(this);
if (enableExport) if (enableExport)
exportHandler = new SaveableExportHandler(this); exportHandler = new SaveableExportHandler(this);
list.setTransferHandler(new DefaultTransferHandler(importHander, exportHandler)); list.setTransferHandler(new DefaultTransferHandler(new TransferablePolicyImportHandler(mutableTransferablePolicy), exportHandler));
list.setDragEnabled(enableExport); list.setDragEnabled(enableExport);
if (enableRemoveAction) { if (enableRemoveAction) {
@ -92,12 +82,12 @@ public class FileBotList extends JPanel implements Saveable, TransferablePolicyS
public void setTransferablePolicy(TransferablePolicy transferablePolicy) { public void setTransferablePolicy(TransferablePolicy transferablePolicy) {
this.transferablePolicy = transferablePolicy; mutableTransferablePolicy.setTransferablePolicy(transferablePolicy);
} }
public TransferablePolicy getTransferablePolicy() { public TransferablePolicy getTransferablePolicy() {
return transferablePolicy; return mutableTransferablePolicy;
} }
@ -112,10 +102,8 @@ public class FileBotList extends JPanel implements Saveable, TransferablePolicyS
if (titledBorder != null) if (titledBorder != null)
titledBorder.setTitle(title); titledBorder.setTitle(title);
if (isVisible()) { revalidate();
revalidate(); repaint();
repaint();
}
} }
@ -153,8 +141,8 @@ public class FileBotList extends JPanel implements Saveable, TransferablePolicyS
public void load(List<File> files) { public void load(List<File> files) {
FileTransferable tr = new FileTransferable(files); FileTransferable tr = new FileTransferable(files);
if (transferablePolicy.accept(tr)) if (mutableTransferablePolicy.accept(tr))
transferablePolicy.handleTransferable(tr, false); mutableTransferablePolicy.handleTransferable(tr, false);
} }
private final AbstractAction removeAction = new AbstractAction("Remove") { private final AbstractAction removeAction = new AbstractAction("Remove") {

View File

@ -20,19 +20,21 @@ import net.sourceforge.filebot.ui.panel.subtitle.SubtitlePanel;
public class FileBotPanel extends JPanel { public class FileBotPanel extends JPanel {
private static final List<FileBotPanel> registry = new ArrayList<FileBotPanel>(); private static List<FileBotPanel> registry;
static {
registry.add(new ListPanel());
registry.add(new RenamePanel());
registry.add(new AnalyzePanel());
registry.add(new SearchPanel());
registry.add(new SubtitlePanel());
registry.add(new SfvPanel());
}
public static List<FileBotPanel> getAvailablePanels() { public static synchronized List<FileBotPanel> getAvailablePanels() {
if (registry == null) {
registry = new ArrayList<FileBotPanel>(6);
registry.add(new ListPanel());
registry.add(new RenamePanel());
registry.add(new AnalyzePanel());
registry.add(new SearchPanel());
registry.add(new SubtitlePanel());
registry.add(new SfvPanel());
}
return Collections.unmodifiableList(registry); return Collections.unmodifiableList(registry);
} }

View File

@ -33,15 +33,10 @@ class FileBotPanelSelectionList extends JList {
setBorder(new EmptyBorder(4, 5, 4, 5)); setBorder(new EmptyBorder(4, 5, 4, 5));
// initialize "drag over" panel selection
new DropTarget(this, new DragDropListener()); new DropTarget(this, new DragDropListener());
SimpleListModel model = new SimpleListModel(); setModel(new SimpleListModel(FileBotPanel.getAvailablePanels()));
for (FileBotPanel panel : FileBotPanel.getAvailablePanels()) {
model.add(panel);
}
setModel(model);
} }
@ -110,6 +105,7 @@ class FileBotPanelSelectionList extends JList {
} }
@Override
public void drop(DropTargetDropEvent dtde) { public void drop(DropTargetDropEvent dtde) {
} }

View File

@ -4,42 +4,30 @@ package net.sourceforge.filebot.ui;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import net.sourceforge.filebot.resources.ResourceManager; import net.sourceforge.filebot.resources.ResourceManager;
public class FileBotTabComponent extends JPanel { public class FileBotTabComponent extends JPanel {
private final JLabel label; private final JLabel label = new JLabel();
private final JButton closeButton = createCloseButton();
public FileBotTabComponent() { public FileBotTabComponent() {
this("", null);
}
public FileBotTabComponent(String title, Icon icon) {
super(new BorderLayout(0, 0)); super(new BorderLayout(0, 0));
setOpaque(false); setOpaque(false);
label = new JLabel(title, SwingConstants.LEFT);
label.setIcon(icon);
label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 2)); label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 2));
add(label, BorderLayout.CENTER); add(label, BorderLayout.CENTER);
add(new CloseButton(tabCloseAction), BorderLayout.EAST); add(closeButton, BorderLayout.EAST);
} }
@ -58,34 +46,25 @@ public class FileBotTabComponent extends JPanel {
} }
public void close() { public JButton getCloseButton() {
JTabbedPane tabs = (JTabbedPane) SwingUtilities.getAncestorOfClass(JTabbedPane.class, FileBotTabComponent.this); return closeButton;
tabs.removeTabAt(tabs.indexOfTabComponent(FileBotTabComponent.this));
} }
private final AbstractAction tabCloseAction = new AbstractAction(null, null) {
private JButton createCloseButton() {
JButton button = new JButton();
public void actionPerformed(ActionEvent e) { button.setContentAreaFilled(false);
close(); button.setBorderPainted(false);
} button.setFocusable(false);
}; button.setRolloverEnabled(true);
private class CloseButton extends JButton {
public CloseButton(AbstractAction action) { button.setIcon(ResourceManager.getIcon("tab.close"));
super(action); button.setRolloverIcon(ResourceManager.getIcon("tab.close.hover"));
setContentAreaFilled(false); button.setPreferredSize(new Dimension(17, 17));
setBorderPainted(false);
setFocusable(false); return button;
}
setIcon(ResourceManager.getIcon("tab.close"));
setRolloverIcon(ResourceManager.getIcon("tab.close.hover"));
setRolloverEnabled(true);
setPreferredSize(new Dimension(17, 17));
}
};
} }

View File

@ -26,15 +26,9 @@ import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel; import javax.swing.tree.TreeSelectionModel;
import net.sourceforge.filebot.resources.ResourceManager; import net.sourceforge.filebot.resources.ResourceManager;
import net.sourceforge.filebot.ui.transfer.TransferablePolicySupport;
import net.sourceforge.filebot.ui.transferablepolicies.NullTransferablePolicy;
import net.sourceforge.filebot.ui.transferablepolicies.TransferablePolicy;
public class FileBotTree extends JTree implements TransferablePolicySupport { public class FileBotTree extends JTree {
private TransferablePolicy transferablePolicy = new NullTransferablePolicy();
public FileBotTree() { public FileBotTree() {
super(new DefaultTreeModel(new DefaultMutableTreeNode())); super(new DefaultTreeModel(new DefaultMutableTreeNode()));
@ -57,16 +51,6 @@ public class FileBotTree extends JTree implements TransferablePolicySupport {
} }
public void setTransferablePolicy(TransferablePolicy transferablePolicy) {
this.transferablePolicy = transferablePolicy;
}
public TransferablePolicy getTransferablePolicy() {
return transferablePolicy;
}
public List<File> convertToList() { public List<File> convertToList() {
TreeNode node = (TreeNode) getModel().getRoot(); TreeNode node = (TreeNode) getModel().getRoot();

View File

@ -10,7 +10,7 @@ import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import net.sourceforge.filebot.ui.transfer.FileTransferable; import net.sourceforge.filebot.ui.transfer.FileTransferable;
import net.sourceforge.filebot.ui.transfer.TransferablePolicySupport; import net.sourceforge.filebot.ui.transferablepolicies.TransferablePolicy;
import net.sourceforge.tuned.MessageBus; import net.sourceforge.tuned.MessageBus;
import net.sourceforge.tuned.MessageHandler; import net.sourceforge.tuned.MessageHandler;
@ -18,18 +18,17 @@ import net.sourceforge.tuned.MessageHandler;
public class FileTransferableMessageHandler implements MessageHandler { public class FileTransferableMessageHandler implements MessageHandler {
private final String name; private final String name;
private final TransferablePolicySupport transferablePolicySupport; private final TransferablePolicy transferablePolicy;
public FileTransferableMessageHandler(String name, TransferablePolicySupport transferablePolicySupport) { public FileTransferableMessageHandler(String name, TransferablePolicy transferablePolicy) {
this.name = name; this.name = name;
this.transferablePolicySupport = transferablePolicySupport; this.transferablePolicy = transferablePolicy;
} }
@Override @Override
public void handle(String topic, String... messages) { public void handle(String topic, String... messages) {
// change panel // change panel
MessageBus.getDefault().publish("panel", name); MessageBus.getDefault().publish("panel", name);
@ -50,6 +49,6 @@ public class FileTransferableMessageHandler implements MessageHandler {
} }
} }
transferablePolicySupport.getTransferablePolicy().handleTransferable(new FileTransferable(files), true); transferablePolicy.handleTransferable(new FileTransferable(files), true);
} }
} }

View File

@ -62,7 +62,7 @@ public class AnalyzePanel extends FileBotPanel {
fileTreePanel.getFileTree().addPropertyChangeListener(FileTree.CONTENT_PROPERTY, fileTreeChangeListener); fileTreePanel.getFileTree().addPropertyChangeListener(FileTree.CONTENT_PROPERTY, fileTreeChangeListener);
MessageBus.getDefault().addMessageHandler(getPanelName(), new FileTransferableMessageHandler(getPanelName(), fileTreePanel.getFileTree())); MessageBus.getDefault().addMessageHandler(getPanelName(), new FileTransferableMessageHandler(getPanelName(), fileTreePanel.getFileTree().getTransferablePolicy()));
} }

View File

@ -20,6 +20,7 @@ import net.sourceforge.filebot.ui.FileBotTree;
import net.sourceforge.filebot.ui.transfer.DefaultTransferHandler; import net.sourceforge.filebot.ui.transfer.DefaultTransferHandler;
import net.sourceforge.filebot.ui.transfer.FileTransferable; import net.sourceforge.filebot.ui.transfer.FileTransferable;
import net.sourceforge.filebot.ui.transfer.TransferablePolicyImportHandler; import net.sourceforge.filebot.ui.transfer.TransferablePolicyImportHandler;
import net.sourceforge.filebot.ui.transferablepolicies.TransferablePolicy;
class FileTree extends FileBotTree { class FileTree extends FileBotTree {
@ -29,13 +30,19 @@ class FileTree extends FileBotTree {
private PostProcessor postProcessor; private PostProcessor postProcessor;
private final FileTreeTransferablePolicy transferablePolicy;
public FileTree() { public FileTree() {
FileTreeTransferablePolicy transferPolicy = new FileTreeTransferablePolicy(this); transferablePolicy = new FileTreeTransferablePolicy(this);
transferPolicy.addPropertyChangeListener(LOADING_PROPERTY, new LoadingPropertyChangeListener()); transferablePolicy.addPropertyChangeListener(LOADING_PROPERTY, new LoadingPropertyChangeListener());
setTransferablePolicy(transferPolicy); setTransferHandler(new DefaultTransferHandler(new TransferablePolicyImportHandler(transferablePolicy), null));
setTransferHandler(new DefaultTransferHandler(new TransferablePolicyImportHandler(this), null)); }
public TransferablePolicy getTransferablePolicy() {
return transferablePolicy;
} }
@ -64,14 +71,14 @@ class FileTree extends FileBotTree {
public void load(List<File> files) { public void load(List<File> files) {
FileTransferable tr = new FileTransferable(files); FileTransferable tr = new FileTransferable(files);
if (getTransferablePolicy().accept(tr)) if (transferablePolicy.accept(tr))
getTransferablePolicy().handleTransferable(tr, true); transferablePolicy.handleTransferable(tr, true);
} }
@Override @Override
public void clear() { public void clear() {
((FileTreeTransferablePolicy) getTransferablePolicy()).reset(); transferablePolicy.reset();
super.clear(); super.clear();
contentChanged(); contentChanged();
@ -105,7 +112,7 @@ class FileTree extends FileBotTree {
} }
private class PostProcessor extends SwingWorker<List<File>, Object> { private class PostProcessor extends SwingWorker<List<File>, Void> {
@Override @Override
protected List<File> doInBackground() throws Exception { protected List<File> doInBackground() throws Exception {

View File

@ -50,7 +50,7 @@ class FileTreePanel extends JPanel {
return fileTree; return fileTree;
} }
private final LoadAction loadAction = new LoadAction(fileTree); private final LoadAction loadAction = new LoadAction(fileTree.getTransferablePolicy());
private final AbstractAction clearAction = new AbstractAction("Clear", ResourceManager.getIcon("action.clear")) { private final AbstractAction clearAction = new AbstractAction("Clear", ResourceManager.getIcon("action.clear")) {

View File

@ -22,12 +22,6 @@ class FileTreeTransferablePolicy extends BackgroundFileTransferablePolicy<Defaul
} }
@Override
protected boolean accept(File file) {
return file.isFile() || file.isDirectory();
}
@Override @Override
protected void clear() { protected void clear() {
tree.clear(); tree.clear();

View File

@ -111,7 +111,7 @@ public class SplitPanel extends ToolPanel implements ChangeListener {
} }
private class UpdateTask extends SwingWorker<DefaultTreeModel, Object> { private class UpdateTask extends SwingWorker<DefaultTreeModel, Void> {
private final Collection<File> files; private final Collection<File> files;

View File

@ -59,7 +59,7 @@ public class TypePanel extends ToolPanel {
} }
private class UpdateTask extends SwingWorker<DefaultTreeModel, Object> { private class UpdateTask extends SwingWorker<DefaultTreeModel, Void> {
private final Collection<File> files; private final Collection<File> files;

View File

@ -26,12 +26,6 @@ class FileListTransferablePolicy extends FileTransferablePolicy {
} }
@Override
protected boolean accept(File file) {
return file.isFile() || file.isDirectory();
}
@Override @Override
protected void clear() { protected void clear() {
list.getModel().clear(); list.getModel().clear();

View File

@ -39,7 +39,7 @@ public class ListPanel extends FileBotPanel {
private FileBotList list = new FileBotList(true, true, true); private FileBotList list = new FileBotList(true, true, true);
private SaveAction saveAction = new SaveAction(list); private SaveAction saveAction = new SaveAction(list);
private LoadAction loadAction = new LoadAction(list); private LoadAction loadAction = new LoadAction(list.getTransferablePolicy());
private JTextField textField = new JTextField(String.format("Name - %s", INDEX_VARIABLE), 25); private JTextField textField = new JTextField(String.format("Name - %s", INDEX_VARIABLE), 25);
private SpinnerNumberModel fromSpinnerModel = new SpinnerNumberModel(1, 0, Integer.MAX_VALUE, 1); private SpinnerNumberModel fromSpinnerModel = new SpinnerNumberModel(1, 0, Integer.MAX_VALUE, 1);
@ -90,7 +90,7 @@ public class ListPanel extends FileBotPanel {
TunedUtil.registerActionForKeystroke(this, KeyStroke.getKeyStroke("ENTER"), createAction); TunedUtil.registerActionForKeystroke(this, KeyStroke.getKeyStroke("ENTER"), createAction);
MessageBus.getDefault().addMessageHandler(getPanelName(), new FileTransferableMessageHandler(getPanelName(), list)); MessageBus.getDefault().addMessageHandler(getPanelName(), new FileTransferableMessageHandler(getPanelName(), list.getTransferablePolicy()));
} }

View File

@ -22,12 +22,6 @@ class FilesListTransferablePolicy extends FileTransferablePolicy {
} }
@Override
protected boolean accept(File file) {
return file.isFile() || file.isDirectory();
}
@Override @Override
protected void clear() { protected void clear() {
model.clear(); model.clear();

View File

@ -111,7 +111,7 @@ class MatchAction extends AbstractAction {
} }
private class BackgroundMatcher extends SwingWorker<List<Match>, Object> { private class BackgroundMatcher extends SwingWorker<List<Match>, Void> {
private final RenameList primaryList; private final RenameList primaryList;
private final RenameList secondaryList; private final RenameList secondaryList;

View File

@ -69,12 +69,6 @@ class NamesListTransferablePolicy extends MultiTransferablePolicy {
} }
@Override
protected boolean accept(File file) {
return file.isFile() || file.isDirectory();
}
@Override @Override
protected void load(List<File> files) { protected void load(List<File> files) {
@ -146,7 +140,7 @@ class NamesListTransferablePolicy extends MultiTransferablePolicy {
protected void load(String text) { protected void load(String text) {
List<ListEntry> entries = new ArrayList<ListEntry>(); List<ListEntry> entries = new ArrayList<ListEntry>();
String[] lines = text.split("\n"); String[] lines = text.split("\r?\n");
for (String line : lines) { for (String line : lines) {

View File

@ -25,7 +25,7 @@ import net.sourceforge.filebot.ui.transfer.LoadAction;
class RenameList extends FileBotList { class RenameList extends FileBotList {
public RenameList() { public RenameList() {
super(true, false, true); super(false, true, true);
Box buttons = Box.createHorizontalBox(); Box buttons = Box.createHorizontalBox();
buttons.setBorder(new EmptyBorder(5, 5, 5, 5)); buttons.setBorder(new EmptyBorder(5, 5, 5, 5));
@ -86,7 +86,7 @@ class RenameList extends FileBotList {
} }
}; };
protected final LoadAction loadAction = new LoadAction(this); protected final LoadAction loadAction = new LoadAction(getTransferablePolicy());
private MouseAdapter dndReorderMouseAdapter = new MouseAdapter() { private MouseAdapter dndReorderMouseAdapter = new MouseAdapter() {

View File

@ -3,6 +3,7 @@ package net.sourceforge.filebot.ui.panel.search;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import javax.swing.JComponent;
import net.sourceforge.filebot.resources.ResourceManager; import net.sourceforge.filebot.resources.ResourceManager;
import net.sourceforge.filebot.ui.FileBotList; import net.sourceforge.filebot.ui.FileBotList;
@ -19,11 +20,11 @@ public class EpisodeListPanel extends FileBotList {
public EpisodeListPanel() { public EpisodeListPanel() {
super(false, true, true, false); super(true, true, false);
} }
public FileBotTabComponent getTabComponent() { public JComponent getTabComponent() {
return tabComponent; return tabComponent;
} }

View File

@ -10,7 +10,7 @@ import net.sourceforge.filebot.web.Episode;
import net.sourceforge.filebot.web.EpisodeListClient; import net.sourceforge.filebot.web.EpisodeListClient;
class FetchEpisodeListTask extends SwingWorker<List<Episode>, Object> { class FetchEpisodeListTask extends SwingWorker<List<Episode>, Void> {
private final String showName; private final String showName;
private final EpisodeListClient searchEngine; private final EpisodeListClient searchEngine;

View File

@ -8,7 +8,6 @@ import java.awt.Window;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.io.File;
import java.net.URL; import java.net.URL;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.util.ArrayList; import java.util.ArrayList;
@ -181,41 +180,20 @@ public class SearchPanel extends FileBotPanel {
private final SaveAction saveAction = new SaveAction(null) { private final SaveAction saveAction = new SaveAction(null) {
private Saveable current;
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
Component c = tabbedPane.getSelectedComponent(); Component c = tabbedPane.getSelectedComponent();
if (c instanceof Saveable) { if (c instanceof Saveable) {
current = (Saveable) c; setSaveable((Saveable) c);
super.actionPerformed(e); super.actionPerformed(e);
} }
} }
@Override
protected boolean isSaveable() {
return current.isSaveable();
}
@Override
protected String getDefaultFileName() {
return current.getDefaultFileName();
}
@Override
protected void save(File file) {
current.save(file);
current = null;
}
}; };
private class SearchTask extends SwingWorker<List<String>, Object> { private class SearchTask extends SwingWorker<List<String>, Void> {
private String query; private String query;
private EpisodeListClient client; private EpisodeListClient client;

View File

@ -10,7 +10,7 @@ import java.util.zip.CheckedInputStream;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
public class ChecksumComputationTask extends SwingWorker<Long, Object> { public class ChecksumComputationTask extends SwingWorker<Long, Void> {
private static final int BUFFER_SIZE = 32 * 1024; private static final int BUFFER_SIZE = 32 * 1024;

View File

@ -63,7 +63,7 @@ public class SfvPanel extends FileBotPanel {
// Shortcut DELETE // Shortcut DELETE
TunedUtil.registerActionForKeystroke(this, KeyStroke.getKeyStroke("pressed DELETE"), removeAction); TunedUtil.registerActionForKeystroke(this, KeyStroke.getKeyStroke("pressed DELETE"), removeAction);
MessageBus.getDefault().addMessageHandler(getPanelName(), new FileTransferableMessageHandler(getPanelName(), sfvTable)); MessageBus.getDefault().addMessageHandler(getPanelName(), new FileTransferableMessageHandler(getPanelName(), sfvTable.getTransferablePolicy()));
} }
private final SaveAction saveAction = new SaveAction(sfvTable) { private final SaveAction saveAction = new SaveAction(sfvTable) {
@ -141,7 +141,7 @@ public class SfvPanel extends FileBotPanel {
} }
}; };
private final LoadAction loadAction = new LoadAction(sfvTable); private final LoadAction loadAction = new LoadAction(sfvTable.getTransferablePolicy());
private final AbstractAction clearAction = new AbstractAction("Clear", ResourceManager.getIcon("action.clear")) { private final AbstractAction clearAction = new AbstractAction("Clear", ResourceManager.getIcon("action.clear")) {

View File

@ -20,32 +20,28 @@ import net.sourceforge.filebot.FileFormat;
import net.sourceforge.filebot.ui.panel.sfv.ChecksumTableModel.ChecksumTableModelEvent; import net.sourceforge.filebot.ui.panel.sfv.ChecksumTableModel.ChecksumTableModelEvent;
import net.sourceforge.filebot.ui.panel.sfv.renderer.ChecksumTableCellRenderer; import net.sourceforge.filebot.ui.panel.sfv.renderer.ChecksumTableCellRenderer;
import net.sourceforge.filebot.ui.panel.sfv.renderer.StateIconTableCellRenderer; import net.sourceforge.filebot.ui.panel.sfv.renderer.StateIconTableCellRenderer;
import net.sourceforge.filebot.ui.panel.sfv.renderer.TextTableCellRenderer;
import net.sourceforge.filebot.ui.transfer.DefaultTransferHandler; import net.sourceforge.filebot.ui.transfer.DefaultTransferHandler;
import net.sourceforge.filebot.ui.transfer.ExportHandler; import net.sourceforge.filebot.ui.transfer.ExportHandler;
import net.sourceforge.filebot.ui.transfer.ImportHandler; import net.sourceforge.filebot.ui.transfer.ImportHandler;
import net.sourceforge.filebot.ui.transfer.Saveable; import net.sourceforge.filebot.ui.transfer.Saveable;
import net.sourceforge.filebot.ui.transfer.SaveableExportHandler; import net.sourceforge.filebot.ui.transfer.SaveableExportHandler;
import net.sourceforge.filebot.ui.transfer.TransferablePolicyImportHandler; import net.sourceforge.filebot.ui.transfer.TransferablePolicyImportHandler;
import net.sourceforge.filebot.ui.transfer.TransferablePolicySupport;
import net.sourceforge.filebot.ui.transferablepolicies.BackgroundFileTransferablePolicy;
import net.sourceforge.filebot.ui.transferablepolicies.NullTransferablePolicy;
import net.sourceforge.filebot.ui.transferablepolicies.TransferablePolicy; import net.sourceforge.filebot.ui.transferablepolicies.TransferablePolicy;
class SfvTable extends JTable implements TransferablePolicySupport, Saveable { class SfvTable extends JTable implements Saveable {
private TransferablePolicy transferablePolicy = new NullTransferablePolicy(); private final SfvTransferablePolicy transferablePolicy;
public SfvTable() { public SfvTable() {
final ChecksumTableModel model = (ChecksumTableModel) getModel(); ChecksumTableModel model = (ChecksumTableModel) getModel();
setFillsViewportHeight(true);
transferablePolicy = new SfvTransferablePolicy(model); transferablePolicy = new SfvTransferablePolicy(model);
setModel(model); setModel(model);
setFillsViewportHeight(true);
setAutoCreateRowSorter(true); setAutoCreateRowSorter(true);
setAutoCreateColumnsFromModel(true); setAutoCreateColumnsFromModel(true);
setAutoResizeMode(AUTO_RESIZE_SUBSEQUENT_COLUMNS); setAutoResizeMode(AUTO_RESIZE_SUBSEQUENT_COLUMNS);
@ -54,18 +50,22 @@ class SfvTable extends JTable implements TransferablePolicySupport, Saveable {
setRowHeight(20); setRowHeight(20);
ImportHandler importHandler = new TransferablePolicyImportHandler(this); ImportHandler importHandler = new TransferablePolicyImportHandler(transferablePolicy);
ExportHandler exportHandler = new SaveableExportHandler(this); ExportHandler exportHandler = new SaveableExportHandler(this);
setTransferHandler(new DefaultTransferHandler(importHandler, exportHandler)); setTransferHandler(new DefaultTransferHandler(importHandler, exportHandler));
setDragEnabled(true); setDragEnabled(true);
setDefaultRenderer(ChecksumRow.State.class, new StateIconTableCellRenderer()); setDefaultRenderer(ChecksumRow.State.class, new StateIconTableCellRenderer());
setDefaultRenderer(String.class, new TextTableCellRenderer());
setDefaultRenderer(Checksum.class, new ChecksumTableCellRenderer()); setDefaultRenderer(Checksum.class, new ChecksumTableCellRenderer());
} }
public TransferablePolicy getTransferablePolicy() {
return transferablePolicy;
}
@Override @Override
protected TableModel createDefaultDataModel() { protected TableModel createDefaultDataModel() {
return new ChecksumTableModel(); return new ChecksumTableModel();
@ -90,22 +90,12 @@ class SfvTable extends JTable implements TransferablePolicySupport, Saveable {
public void clear() { public void clear() {
((BackgroundFileTransferablePolicy<?>) getTransferablePolicy()).reset(); transferablePolicy.reset();
((ChecksumTableModel) getModel()).clear(); ((ChecksumTableModel) getModel()).clear();
} }
public TransferablePolicy getTransferablePolicy() {
return transferablePolicy;
}
public void setTransferablePolicy(TransferablePolicy transferablePolicy) {
this.transferablePolicy = transferablePolicy;
}
public String getDefaultFileName() { public String getDefaultFileName() {
ChecksumTableModel model = (ChecksumTableModel) getModel(); ChecksumTableModel model = (ChecksumTableModel) getModel();
File columnRoot = model.getChecksumColumnRoot(0); File columnRoot = model.getChecksumColumnRoot(0);

View File

@ -27,12 +27,6 @@ class SfvTransferablePolicy extends BackgroundFileTransferablePolicy<ChecksumTab
} }
@Override
protected boolean accept(File file) {
return file.isFile() || file.isDirectory();
}
@Override @Override
protected void clear() { protected void clear() {
tableModel.clear(); tableModel.clear();

View File

@ -5,13 +5,14 @@ package net.sourceforge.filebot.ui.panel.sfv.renderer;
import java.awt.Component; import java.awt.Component;
import javax.swing.JTable; import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import net.sourceforge.filebot.ui.panel.sfv.Checksum; import net.sourceforge.filebot.ui.panel.sfv.Checksum;
public class ChecksumTableCellRenderer extends TextTableCellRenderer { public class ChecksumTableCellRenderer extends DefaultTableCellRenderer {
private ProgressBarTableCellRenderer progressBarRenderer = new ProgressBarTableCellRenderer(); private final ProgressBarTableCellRenderer progressBarRenderer = new ProgressBarTableCellRenderer();
@Override @Override

View File

@ -6,10 +6,10 @@ import java.awt.BorderLayout;
import java.awt.Component; import java.awt.Component;
import java.awt.Rectangle; import java.awt.Rectangle;
import javax.swing.BorderFactory;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JProgressBar; import javax.swing.JProgressBar;
import javax.swing.JTable; import javax.swing.JTable;
import javax.swing.border.EmptyBorder;
import javax.swing.table.TableCellRenderer; import javax.swing.table.TableCellRenderer;
import net.sourceforge.filebot.ui.panel.sfv.Checksum; import net.sourceforge.filebot.ui.panel.sfv.Checksum;
@ -17,17 +17,17 @@ import net.sourceforge.filebot.ui.panel.sfv.Checksum;
public class ProgressBarTableCellRenderer extends JPanel implements TableCellRenderer { public class ProgressBarTableCellRenderer extends JPanel implements TableCellRenderer {
private JProgressBar progressBar = new JProgressBar(0, 100); private final JProgressBar progressBar = new JProgressBar(0, 100);
public ProgressBarTableCellRenderer() { public ProgressBarTableCellRenderer() {
super(new BorderLayout()); super(new BorderLayout());
progressBar.setStringPainted(true); progressBar.setStringPainted(true);
add(progressBar, BorderLayout.CENTER); add(progressBar, BorderLayout.CENTER);
int margin = 2; setBorder(new EmptyBorder(2, 2, 2, 2));
setBorder(BorderFactory.createEmptyBorder(margin, margin, margin, margin));
} }
@ -50,6 +50,7 @@ public class ProgressBarTableCellRenderer extends JPanel implements TableCellRen
/** /**
* Overridden for performance reasons. * Overridden for performance reasons.
*/ */
@Override
public void repaint(long tm, int x, int y, int width, int height) { public void repaint(long tm, int x, int y, int width, int height) {
} }
@ -57,6 +58,7 @@ public class ProgressBarTableCellRenderer extends JPanel implements TableCellRen
/** /**
* Overridden for performance reasons. * Overridden for performance reasons.
*/ */
@Override
public void repaint(Rectangle r) { public void repaint(Rectangle r) {
} }
@ -64,6 +66,7 @@ public class ProgressBarTableCellRenderer extends JPanel implements TableCellRen
/** /**
* Overridden for performance reasons. * Overridden for performance reasons.
*/ */
@Override
public void repaint() { public void repaint() {
} }
@ -71,6 +74,7 @@ public class ProgressBarTableCellRenderer extends JPanel implements TableCellRen
/** /**
* Overridden for performance reasons. * Overridden for performance reasons.
*/ */
@Override
public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) { public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {
} }

View File

@ -7,13 +7,14 @@ import java.awt.Component;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.JTable; import javax.swing.JTable;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableCellRenderer;
import net.sourceforge.filebot.resources.ResourceManager; import net.sourceforge.filebot.resources.ResourceManager;
import net.sourceforge.filebot.ui.panel.sfv.ChecksumRow; import net.sourceforge.filebot.ui.panel.sfv.ChecksumRow;
import net.sourceforge.filebot.ui.panel.sfv.ChecksumRow.State; import net.sourceforge.filebot.ui.panel.sfv.ChecksumRow.State;
public class StateIconTableCellRenderer extends TextTableCellRenderer { public class StateIconTableCellRenderer extends DefaultTableCellRenderer {
private Icon warning = ResourceManager.getIcon("status.warning"); private Icon warning = ResourceManager.getIcon("status.warning");
private Icon error = ResourceManager.getIcon("status.error"); private Icon error = ResourceManager.getIcon("status.error");
@ -46,8 +47,6 @@ public class StateIconTableCellRenderer extends TextTableCellRenderer {
case UNKNOWN: case UNKNOWN:
setIcon(unknown); setIcon(unknown);
break; break;
default:
break;
} }
return this; return this;

View File

@ -1,27 +0,0 @@
package net.sourceforge.filebot.ui.panel.sfv.renderer;
import java.awt.Component;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableCellRenderer;
public class TextTableCellRenderer extends DefaultTableCellRenderer {
public TextTableCellRenderer() {
setVerticalAlignment(SwingConstants.CENTER);
setHorizontalAlignment(SwingConstants.LEFT);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
super.getTableCellRendererComponent(table, value, isSelected, false, row, column);
return this;
}
}

View File

@ -20,4 +20,9 @@ public enum ArchiveType {
return UNKNOWN; return UNKNOWN;
} }
public String getExtension() {
return toString().toLowerCase();
}
} }

View File

@ -11,7 +11,7 @@ import net.sourceforge.filebot.web.SubtitleClient;
import net.sourceforge.filebot.web.SubtitleDescriptor; import net.sourceforge.filebot.web.SubtitleDescriptor;
class FetchSubtitleListTask extends SwingWorker<List<? extends SubtitleDescriptor>, Object> { class FetchSubtitleListTask extends SwingWorker<List<? extends SubtitleDescriptor>, Void> {
private final SubtitleClient client; private final SubtitleClient client;
private final MovieDescriptor descriptor; private final MovieDescriptor descriptor;

View File

@ -0,0 +1,121 @@
package net.sourceforge.filebot.ui.panel.subtitle;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import net.sourceforge.filebot.resources.ResourceManager;
import net.sourceforge.filebot.ui.FileBotTabComponent;
public class FileBotTab<T extends JComponent> extends JPanel {
private final FileBotTabComponent tabComponent = new FileBotTabComponent();
private final T component;
private ImageIcon icon;
private boolean loading = false;
public FileBotTab(T component) {
super(new BorderLayout());
this.component = component;
tabComponent.getCloseButton().addActionListener(closeAction);
add(component, BorderLayout.CENTER);
}
public void addTo(JTabbedPane tabbedPane) {
tabbedPane.addTab(this.getTitle(), this);
tabbedPane.setTabComponentAt(tabbedPane.indexOfComponent(this), tabComponent);
}
public void close() {
if (!isClosed()) {
getTabbedPane().remove(this);
}
}
public boolean isClosed() {
JTabbedPane tabbedPane = getTabbedPane();
if (tabbedPane == null)
return true;
return getTabbedPane().indexOfComponent(this) < 0;
}
private JTabbedPane getTabbedPane() {
return (JTabbedPane) SwingUtilities.getAncestorOfClass(JTabbedPane.class, this);
}
public T getComponent() {
return component;
}
public FileBotTabComponent getTabComponent() {
return tabComponent;
}
public void setTitle(String title) {
tabComponent.setText(title);
}
public String getTitle() {
return tabComponent.getText();
}
public void setIcon(ImageIcon icon) {
this.icon = icon;
if (!loading) {
tabComponent.setIcon(icon);
}
}
public ImageIcon getIcon() {
return icon;
}
public void setLoading(boolean loading) {
this.loading = loading;
if (loading) {
tabComponent.setIcon(ResourceManager.getIcon("tab.loading"));
} else {
tabComponent.setIcon(icon);
}
}
private final ActionListener closeAction = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
close();
}
};
}

View File

@ -20,7 +20,7 @@ public class LanguageResolver {
/** /**
* Get the locale for a language. * Get the {@link Locale} for a given language name (e.g. "german").
* *
* @param languageName english name of the language * @param languageName english name of the language
* @return the locale for this language or null if no locale for this language exists * @return the locale for this language or null if no locale for this language exists
@ -56,6 +56,13 @@ public class LanguageResolver {
} }
/**
* Find the {@link Locale} for a given language name.
*
* @param languageName lower-case language name
* @return {@link Locale} for the given language, or null if no matching {@link Locale} is
* available
*/
private Locale findLocale(String languageName) { private Locale findLocale(String languageName) {
for (Locale locale : Locale.getAvailableLocales()) { for (Locale locale : Locale.getAvailableLocales()) {
if (locale.getDisplayLanguage(Locale.ENGLISH).toLowerCase().equals(languageName)) if (locale.getDisplayLanguage(Locale.ENGLISH).toLowerCase().equals(languageName))

View File

@ -12,8 +12,6 @@ import javax.swing.JLabel;
import javax.swing.JList; import javax.swing.JList;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
import net.sourceforge.filebot.resources.ResourceManager;
import net.sourceforge.filebot.web.SubtitleDescriptor;
import net.sourceforge.tuned.ui.ColorTintImageFilter; import net.sourceforge.tuned.ui.ColorTintImageFilter;
import net.sourceforge.tuned.ui.IconViewCellRenderer; import net.sourceforge.tuned.ui.IconViewCellRenderer;
@ -44,18 +42,17 @@ public class SubtitleCellRenderer extends IconViewCellRenderer {
public void configureListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { public void configureListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.configureListCellRendererComponent(list, value, index, isSelected, cellHasFocus); super.configureListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
SubtitleDescriptor subtitle = (SubtitleDescriptor) value; SubtitlePackage subtitle = (SubtitlePackage) value;
setText(subtitle.getName()); setText(subtitle.getName());
info1.setText(subtitle.getLanguageName()); info1.setText(subtitle.getLanguageName());
info2.setText(subtitle.getAuthor());
icon = (ResourceManager.getFlagIcon(LanguageResolver.getDefault().getLocale(subtitle.getLanguageName()).getLanguage())); icon = subtitle.getLanguageIcon();
info1.setIcon(icon); info1.setIcon(icon);
ImageIcon icon = ResourceManager.getArchiveIcon(subtitle.getArchiveType()); ImageIcon icon = subtitle.getArchiveIcon();
if (isSelected) { if (isSelected) {
setIcon(new ImageIcon(createImage(new FilteredImageSource(icon.getImage().getSource(), new ColorTintImageFilter(list.getSelectionBackground(), 0.5f))))); setIcon(new ImageIcon(createImage(new FilteredImageSource(icon.getImage().getSource(), new ColorTintImageFilter(list.getSelectionBackground(), 0.5f)))));

View File

@ -0,0 +1,41 @@
package net.sourceforge.filebot.ui.panel.subtitle;
import java.util.List;
import javax.swing.BoxLayout;
import javax.swing.JPanel;
import net.sourceforge.filebot.web.SubtitleDescriptor;
import net.sourceforge.tuned.ui.SimpleListModel;
public class SubtitleDownloadPanel extends JPanel {
private final SubtitlePackagePanel packagePanel = new SubtitlePackagePanel();
public SubtitleDownloadPanel() {
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
add(packagePanel);
}
public SubtitlePackagePanel getPackagePanel() {
return packagePanel;
}
public void addSubtitleDescriptors(List<? extends SubtitleDescriptor> subtitleDescriptors) {
SimpleListModel model = new SimpleListModel();
for (SubtitleDescriptor subtitleDescriptor : subtitleDescriptors) {
model.add(new SubtitlePackage(subtitleDescriptor));
}
//TODO real add, not setModel
packagePanel.setModel(model);
}
}

View File

@ -6,7 +6,7 @@ import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport; import java.beans.PropertyChangeSupport;
import javax.swing.Icon; import javax.swing.ImageIcon;
import net.sourceforge.filebot.resources.ResourceManager; import net.sourceforge.filebot.resources.ResourceManager;
import net.sourceforge.filebot.web.SubtitleDescriptor; import net.sourceforge.filebot.web.SubtitleDescriptor;
@ -17,13 +17,20 @@ public class SubtitlePackage {
private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this); private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
private DownloadTask downloadTask = null;
private final SubtitleDescriptor subtitleDescriptor; private final SubtitleDescriptor subtitleDescriptor;
private final ImageIcon archiveIcon;
private final ImageIcon languageIcon;
private DownloadTask downloadTask;
public SubtitlePackage(SubtitleDescriptor subtitleDescriptor) { public SubtitlePackage(SubtitleDescriptor subtitleDescriptor) {
this.subtitleDescriptor = subtitleDescriptor; this.subtitleDescriptor = subtitleDescriptor;
archiveIcon = ResourceManager.getArchiveIcon(subtitleDescriptor.getArchiveType());
languageIcon = ResourceManager.getFlagIcon(LanguageResolver.getDefault().getLanguageCode(subtitleDescriptor.getLanguageName()));
} }
@ -37,8 +44,8 @@ public class SubtitlePackage {
} }
public Icon getArchiveIcon() { public ImageIcon getArchiveIcon() {
return ResourceManager.getArchiveIcon(getArchiveType().toString()); return archiveIcon;
} }
@ -47,8 +54,8 @@ public class SubtitlePackage {
} }
public Icon getLanguageIcon() { public ImageIcon getLanguageIcon() {
return ResourceManager.getFlagIcon(LanguageResolver.getDefault().getLanguageCode(getLanguageName())); return languageIcon;
} }
@ -57,7 +64,7 @@ public class SubtitlePackage {
throw new IllegalStateException("Download has been started already"); throw new IllegalStateException("Download has been started already");
downloadTask = subtitleDescriptor.createDownloadTask(); downloadTask = subtitleDescriptor.createDownloadTask();
downloadTask.addPropertyChangeListener(new DownloadTaskPropertyChangeRelay()); downloadTask.addPropertyChangeListener(new DownloadTaskPropertyChangeAdapter());
downloadTask.execute(); downloadTask.execute();
} }
@ -81,7 +88,7 @@ public class SubtitlePackage {
} }
private class DownloadTaskPropertyChangeRelay implements PropertyChangeListener { private class DownloadTaskPropertyChangeAdapter implements PropertyChangeListener {
@Override @Override
public void propertyChange(PropertyChangeEvent evt) { public void propertyChange(PropertyChangeEvent evt) {

View File

@ -20,25 +20,23 @@ import java.util.TreeSet;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JToggleButton; import javax.swing.JToggleButton;
import javax.swing.JToolTip;
import javax.swing.ListModel; import javax.swing.ListModel;
import net.sourceforge.filebot.Settings; import net.sourceforge.filebot.Settings;
import net.sourceforge.filebot.resources.ResourceManager; import net.sourceforge.filebot.resources.ResourceManager;
import net.sourceforge.filebot.web.SubtitleDescriptor;
import net.sourceforge.tuned.ui.IconViewPanel; import net.sourceforge.tuned.ui.IconViewPanel;
import net.sourceforge.tuned.ui.SimpleListModel; import net.sourceforge.tuned.ui.SimpleListModel;
public class SubtitleViewPanel extends IconViewPanel { public class SubtitlePackagePanel extends IconViewPanel {
private final JPanel languageFilterPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 1));
private ListModel unfilteredModel = new SimpleListModel(); private ListModel unfilteredModel = new SimpleListModel();
private JPanel languageFilterPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 1));
private Map<String, Boolean> languageFilterSelection = new TreeMap<String, Boolean>(String.CASE_INSENSITIVE_ORDER); private Map<String, Boolean> languageFilterSelection = new TreeMap<String, Boolean>(String.CASE_INSENSITIVE_ORDER);
public SubtitleViewPanel() { public SubtitlePackagePanel() {
setCellRenderer(new SubtitleCellRenderer()); setCellRenderer(new SubtitleCellRenderer());
languageFilterPanel.setOpaque(false); languageFilterPanel.setOpaque(false);
@ -71,7 +69,7 @@ public class SubtitleViewPanel extends IconViewPanel {
SortedSet<String> languages = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER); SortedSet<String> languages = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
for (int i = 0; i < unfilteredModel.getSize(); i++) { for (int i = 0; i < unfilteredModel.getSize(); i++) {
SubtitleDescriptor subtitle = (SubtitleDescriptor) unfilteredModel.getElementAt(i); SubtitlePackage subtitle = (SubtitlePackage) unfilteredModel.getElementAt(i);
languages.add(subtitle.getLanguageName()); languages.add(subtitle.getLanguageName());
} }
@ -90,7 +88,7 @@ public class SubtitleViewPanel extends IconViewPanel {
SimpleListModel model = new SimpleListModel(); SimpleListModel model = new SimpleListModel();
for (int i = 0; i < unfilteredModel.getSize(); i++) { for (int i = 0; i < unfilteredModel.getSize(); i++) {
SubtitleDescriptor subtitle = (SubtitleDescriptor) unfilteredModel.getElementAt(i); SubtitlePackage subtitle = (SubtitlePackage) unfilteredModel.getElementAt(i);
if (isLanguageSelected(subtitle.getLanguageName())) { if (isLanguageSelected(subtitle.getLanguageName())) {
model.add(subtitle); model.add(subtitle);
@ -106,6 +104,12 @@ public class SubtitleViewPanel extends IconViewPanel {
} }
public void setLanguageSelected(String language, boolean selected) {
languageFilterSelection.put(language, selected);
Settings.getSettings().putBooleanMapEntry(Settings.SUBTITLE_LANGUAGE, language, selected);
}
private LanguageFilterButton createLanguageFilterButton(String language) { private LanguageFilterButton createLanguageFilterButton(String language) {
Locale locale = LanguageResolver.getDefault().getLocale(language); Locale locale = LanguageResolver.getDefault().getLocale(language);
@ -132,8 +136,7 @@ public class SubtitleViewPanel extends IconViewPanel {
public void itemStateChanged(ItemEvent e) { public void itemStateChanged(ItemEvent e) {
boolean selected = (e.getStateChange() == ItemEvent.SELECTED); boolean selected = (e.getStateChange() == ItemEvent.SELECTED);
languageFilterSelection.put(language, selected); setLanguageSelected(language, selected);
Settings.getSettings().putBooleanMapEntry(Settings.SUBTITLE_LANGUAGE, language, selected);
updateFilteredModel(); updateFilteredModel();
} }
@ -170,19 +173,15 @@ public class SubtitleViewPanel extends IconViewPanel {
protected void paintComponent(Graphics g) { protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g; Graphics2D g2d = (Graphics2D) g;
AlphaComposite composite = AlphaComposite.SrcOver.derive(isSelected() ? 1.0f : 0.2f); // make transparent if not selected
g2d.setComposite(composite); if (!isSelected()) {
AlphaComposite composite = AlphaComposite.SrcOver.derive(0.2f);
g2d.setComposite(composite);
}
super.paintComponent(g2d); super.paintComponent(g2d);
} }
} }
@Override
public JToolTip createToolTip() {
System.out.println("SubtitleViewPanel.createToolTip()");
return super.createToolTip();
}
} }

View File

@ -30,7 +30,6 @@ import net.sourceforge.filebot.FileBotUtil;
import net.sourceforge.filebot.Settings; import net.sourceforge.filebot.Settings;
import net.sourceforge.filebot.resources.ResourceManager; import net.sourceforge.filebot.resources.ResourceManager;
import net.sourceforge.filebot.ui.FileBotPanel; import net.sourceforge.filebot.ui.FileBotPanel;
import net.sourceforge.filebot.ui.FileBotTabComponent;
import net.sourceforge.filebot.ui.HistoryPanel; import net.sourceforge.filebot.ui.HistoryPanel;
import net.sourceforge.filebot.ui.MessageManager; import net.sourceforge.filebot.ui.MessageManager;
import net.sourceforge.filebot.ui.SelectDialog; import net.sourceforge.filebot.ui.SelectDialog;
@ -133,7 +132,7 @@ public class SubtitlePanel extends FileBotPanel {
}; };
private class SearchTask extends SwingWorker<List<MovieDescriptor>, Object> { private class SearchTask extends SwingWorker<List<MovieDescriptor>, Void> {
private final String query; private final String query;
private final SubtitleClient client; private final SubtitleClient client;
@ -155,26 +154,27 @@ public class SubtitlePanel extends FileBotPanel {
private class SearchTaskListener extends SwingWorkerPropertyChangeAdapter { private class SearchTaskListener extends SwingWorkerPropertyChangeAdapter {
private SubtitleViewPanel subtitleSearchResultPanel; private FileBotTab<SubtitleDownloadPanel> downloadPanel;
private FileBotTabComponent tabComponent;
@Override @Override
public void started(PropertyChangeEvent evt) { public void started(PropertyChangeEvent evt) {
SearchTask task = (SearchTask) evt.getSource(); SearchTask task = (SearchTask) evt.getSource();
subtitleSearchResultPanel = new SubtitleViewPanel(); downloadPanel = new FileBotTab<SubtitleDownloadPanel>(new SubtitleDownloadPanel());
tabComponent = new FileBotTabComponent(task.query, ResourceManager.getIcon("tab.loading"));
tabbedPane.addTab(task.query, subtitleSearchResultPanel); downloadPanel.setTitle(task.query);
tabbedPane.setTabComponentAt(tabbedPane.indexOfComponent(subtitleSearchResultPanel), tabComponent); downloadPanel.setLoading(true);
downloadPanel.setIcon(task.client.getIcon());
downloadPanel.addTo(tabbedPane);
} }
@Override @Override
public void done(PropertyChangeEvent evt) { public void done(PropertyChangeEvent evt) {
// tab might have been closed // tab might have been closed
if (tabbedPane.indexOfComponent(subtitleSearchResultPanel) < 0) if (downloadPanel.isClosed())
return; return;
SearchTask searchTask = (SearchTask) evt.getSource(); SearchTask searchTask = (SearchTask) evt.getSource();
@ -185,18 +185,26 @@ public class SubtitlePanel extends FileBotPanel {
MovieDescriptor descriptor = selectDescriptor(desriptors, searchTask.client); MovieDescriptor descriptor = selectDescriptor(desriptors, searchTask.client);
if (descriptor == null) { if (descriptor == null) {
// user canceled selection, or no subtitles available
if (desriptors.isEmpty()) { if (desriptors.isEmpty()) {
MessageManager.showWarning(String.format("\"%s\" has not been found.", searchTask.query)); MessageManager.showWarning(String.format("\"%s\" has not been found.", searchTask.query));
} }
tabbedPane.remove(subtitleSearchResultPanel); downloadPanel.close();
return; return;
} }
fetchSubtitles(descriptor, searchTask.client); searchFieldCompletion.addTerm(descriptor.getTitle());
Settings.getSettings().putStringList(Settings.SUBTITLE_HISTORY, searchFieldCompletion.getTerms());
downloadPanel.setTitle(descriptor.getTitle());
FetchSubtitleListTask fetchListTask = new FetchSubtitleListTask(descriptor, searchTask.client);
fetchListTask.addPropertyChangeListener(new FetchSubtitleListTaskListener(downloadPanel));
fetchListTask.execute();
} catch (Exception e) { } catch (Exception e) {
tabbedPane.remove(subtitleSearchResultPanel); downloadPanel.close();
Throwable cause = FileBotUtil.getRootCause(e); Throwable cause = FileBotUtil.getRootCause(e);
@ -224,42 +232,27 @@ public class SubtitlePanel extends FileBotPanel {
selectDialog.setIconImage(client.getIcon().getImage()); selectDialog.setIconImage(client.getIcon().getImage());
selectDialog.setVisible(true); selectDialog.setVisible(true);
// selected value or null if cancelled by the user // selected value or null if canceled by the user
return selectDialog.getSelectedValue(); return selectDialog.getSelectedValue();
} }
private void fetchSubtitles(MovieDescriptor descriptor, SubtitleClient client) {
Settings.getSettings().putStringList(Settings.SUBTITLE_HISTORY, searchFieldCompletion.getTerms());
searchFieldCompletion.addTerm(descriptor.getTitle());
tabComponent.setText(descriptor.getTitle());
FetchSubtitleListTask fetchListTask = new FetchSubtitleListTask(descriptor, client);
fetchListTask.addPropertyChangeListener(new FetchSubtitleListTaskListener(subtitleSearchResultPanel, tabComponent));
fetchListTask.execute();
}
} }
private class FetchSubtitleListTaskListener extends SwingWorkerPropertyChangeAdapter { private class FetchSubtitleListTaskListener extends SwingWorkerPropertyChangeAdapter {
private final SubtitleViewPanel subtitleSearchResultPanel; private final FileBotTab<SubtitleDownloadPanel> downloadPanel;
private final FileBotTabComponent tabComponent;
public FetchSubtitleListTaskListener(SubtitleViewPanel subtitleSearchResultPanel, FileBotTabComponent tabComponent) { public FetchSubtitleListTaskListener(FileBotTab<SubtitleDownloadPanel> downloadPanel) {
this.subtitleSearchResultPanel = subtitleSearchResultPanel; this.downloadPanel = downloadPanel;
this.tabComponent = tabComponent;
} }
@Override @Override
public void done(PropertyChangeEvent evt) { public void done(PropertyChangeEvent evt) {
// tab might have been closed // tab might have been closed
if (tabbedPane.indexOfComponent(subtitleSearchResultPanel) < 0) if (downloadPanel.isClosed())
return; return;
FetchSubtitleListTask task = (FetchSubtitleListTask) evt.getSource(); FetchSubtitleListTask task = (FetchSubtitleListTask) evt.getSource();
@ -272,17 +265,17 @@ public class SubtitlePanel extends FileBotPanel {
historyPanel.add(task.getDescriptor().toString(), null, task.getClient().getIcon(), info, NumberFormat.getInstance().format(task.getDuration()) + " ms"); historyPanel.add(task.getDescriptor().toString(), null, task.getClient().getIcon(), info, NumberFormat.getInstance().format(task.getDuration()) + " ms");
if (subtitleDescriptors.isEmpty()) { if (subtitleDescriptors.isEmpty()) {
tabbedPane.remove(subtitleSearchResultPanel); MessageManager.showWarning(info);
downloadPanel.close();
return; return;
} }
tabComponent.setIcon(task.getClient().getIcon()); downloadPanel.setLoading(false);
//TODO icon view downloadPanel.getComponent().getPackagePanel().setTitle(info);
//TODO sysout downloadPanel.getComponent().addSubtitleDescriptors(subtitleDescriptors);
System.out.println(subtitleDescriptors);
} catch (Exception e) { } catch (Exception e) {
tabbedPane.remove(subtitleSearchResultPanel); downloadPanel.close();
MessageManager.showWarning(FileBotUtil.getRootCause(e).getMessage()); MessageManager.showWarning(FileBotUtil.getRootCause(e).getMessage());
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e); Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);

View File

@ -20,12 +20,12 @@ public class Unrar {
private static final int sleepInterval = 50; private static final int sleepInterval = 50;
public static void extractFiles(File archive, File destination) throws Exception { public static void extractFiles(File archiveFile, File destinationFolder) throws Exception {
if (command == null) { if (command == null) {
throw new IllegalStateException("Unrar could not be initialized"); throw new IllegalStateException("Unrar could not be initialized");
} }
Process process = command.execute(archive, destination); Process process = command.execute(archiveFile, destinationFolder);
int counter = 0; int counter = 0;
@ -117,7 +117,15 @@ public class Unrar {
ProcessBuilder builder = new ProcessBuilder(executable, "x", "-y", archive.getAbsolutePath()); ProcessBuilder builder = new ProcessBuilder(executable, "x", "-y", archive.getAbsolutePath());
builder.directory(workingDirectory); builder.directory(workingDirectory);
return builder.start(); Process process = builder.start();
// make sure process is non-interactive
// e.g. if input stream is not closed 7z.exe sometimes doesn't exit
process.getInputStream().close();
process.getOutputStream().close();
process.getErrorStream().close();
return process;
} }

View File

@ -92,5 +92,26 @@ public class DefaultTransferHandler extends TransferHandler {
if (clipboardHandler != null) if (clipboardHandler != null)
clipboardHandler.exportToClipboard(comp, clip, action); clipboardHandler.exportToClipboard(comp, clip, action);
} }
public void setImportHandler(ImportHandler importHandler) {
this.importHandler = importHandler;
}
public void setExportHandler(ExportHandler exportHandler) {
this.exportHandler = exportHandler;
}
public void setClipboardHandler(ClipboardHandler clipboardHandler) {
this.clipboardHandler = clipboardHandler;
}
} }

View File

@ -13,19 +13,19 @@ import net.sourceforge.filebot.ui.transferablepolicies.TransferablePolicy;
public class LoadAction extends AbstractAction { public class LoadAction extends AbstractAction {
private TransferablePolicySupport transferablePolicySupport; private final TransferablePolicy transferablePolicy;
public LoadAction(TransferablePolicySupport transferablePolicySupport) { public LoadAction(TransferablePolicy transferablePolicy) {
super("Load", ResourceManager.getIcon("action.load")); super("Load", ResourceManager.getIcon("action.load"));
this.transferablePolicySupport = transferablePolicySupport; this.transferablePolicy = transferablePolicy;
} }
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
JFileChooser chooser = new JFileChooser(); JFileChooser chooser = new JFileChooser();
chooser.setFileFilter(new TransferablePolicyFileFilter(transferablePolicySupport.getTransferablePolicy())); chooser.setFileFilter(new TransferablePolicyFileFilter(transferablePolicy));
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
chooser.setMultiSelectionEnabled(true); chooser.setMultiSelectionEnabled(true);
@ -35,8 +35,6 @@ public class LoadAction extends AbstractAction {
FileTransferable transferable = new FileTransferable(chooser.getSelectedFiles()); FileTransferable transferable = new FileTransferable(chooser.getSelectedFiles());
TransferablePolicy transferablePolicy = transferablePolicySupport.getTransferablePolicy();
boolean add = ((e.getModifiers() & ActionEvent.CTRL_MASK) != 0); boolean add = ((e.getModifiers() & ActionEvent.CTRL_MASK) != 0);
if (transferablePolicy.accept(transferable)) if (transferablePolicy.accept(transferable))

View File

@ -43,6 +43,11 @@ public class SaveAction extends AbstractAction {
} }
protected void setSaveable(Saveable saveable) {
this.saveable = saveable;
}
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
if (!isSaveable()) if (!isSaveable())
return; return;

View File

@ -13,7 +13,7 @@ import net.sourceforge.filebot.ui.transferablepolicies.TransferablePolicy;
public class TransferablePolicyFileFilter extends FileFilter { public class TransferablePolicyFileFilter extends FileFilter {
private TransferablePolicy transferablePolicy; private final TransferablePolicy transferablePolicy;
public TransferablePolicyFileFilter(TransferablePolicy transferablePolicy) { public TransferablePolicyFileFilter(TransferablePolicy transferablePolicy) {

View File

@ -10,15 +10,16 @@ import java.util.logging.Logger;
import javax.swing.TransferHandler; import javax.swing.TransferHandler;
import javax.swing.TransferHandler.TransferSupport; import javax.swing.TransferHandler.TransferSupport;
import net.sourceforge.filebot.ui.transferablepolicies.TransferablePolicy;
public class TransferablePolicyImportHandler implements ImportHandler { public class TransferablePolicyImportHandler implements ImportHandler {
private TransferablePolicySupport transferablePolicySupport; private final TransferablePolicy transferablePolicy;
public TransferablePolicyImportHandler(TransferablePolicySupport transferablePolicySupport) { public TransferablePolicyImportHandler(TransferablePolicy transferablePolicy) {
this.transferablePolicySupport = transferablePolicySupport; this.transferablePolicy = transferablePolicy;
} }
private boolean canImportCache = false; private boolean canImportCache = false;
@ -32,7 +33,7 @@ public class TransferablePolicyImportHandler implements ImportHandler {
Transferable t = support.getTransferable(); Transferable t = support.getTransferable();
try { try {
canImportCache = transferablePolicySupport.getTransferablePolicy().accept(t); canImportCache = transferablePolicy.accept(t);
} catch (InvalidDnDOperationException e) { } catch (InvalidDnDOperationException e) {
// for some reason the last transferable has no drop current // for some reason the last transferable has no drop current
} }
@ -51,7 +52,7 @@ public class TransferablePolicyImportHandler implements ImportHandler {
Transferable t = support.getTransferable(); Transferable t = support.getTransferable();
try { try {
transferablePolicySupport.getTransferablePolicy().handleTransferable(t, add); transferablePolicy.handleTransferable(t, add);
} catch (Exception e) { } catch (Exception e) {
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e); Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
} }

View File

@ -1,11 +0,0 @@
package net.sourceforge.filebot.ui.transfer;
import net.sourceforge.filebot.ui.transferablepolicies.TransferablePolicy;
public interface TransferablePolicySupport {
public TransferablePolicy getTransferablePolicy();
}

View File

@ -85,7 +85,7 @@ public abstract class BackgroundFileTransferablePolicy<V> extends FileTransferab
} }
private class BackgroundWorker extends SwingWorker<Object, V> { private class BackgroundWorker extends SwingWorker<Void, V> {
private final List<File> files; private final List<File> files;
@ -96,7 +96,7 @@ public abstract class BackgroundFileTransferablePolicy<V> extends FileTransferab
@Override @Override
protected Object doInBackground() { protected Void doInBackground() {
load(files); load(files);
return null; return null;

View File

@ -110,7 +110,7 @@ public abstract class FileTransferablePolicy implements TransferablePolicy {
protected boolean accept(File file) { protected boolean accept(File file) {
return false; return file.isFile() || file.isDirectory();
} }

View File

@ -0,0 +1,44 @@
package net.sourceforge.filebot.ui.transferablepolicies;
import java.awt.datatransfer.Transferable;
public class MutableTransferablePolicy implements TransferablePolicy {
private TransferablePolicy transferablePolicy = null;
public void setTransferablePolicy(TransferablePolicy transferablePolicy) {
this.transferablePolicy = transferablePolicy;
}
@Override
public boolean accept(Transferable tr) {
if (transferablePolicy == null)
return false;
return transferablePolicy.accept(tr);
}
@Override
public String getDescription() {
if (transferablePolicy == null)
return null;
return transferablePolicy.getDescription();
}
@Override
public void handleTransferable(Transferable tr, boolean add) {
if (transferablePolicy == null)
return;
transferablePolicy.handleTransferable(tr, add);
}
}

View File

@ -12,16 +12,18 @@ import javax.swing.ImageIcon;
public abstract class EpisodeListClient { public abstract class EpisodeListClient {
private static final List<EpisodeListClient> registry = new ArrayList<EpisodeListClient>(); private static List<EpisodeListClient> registry;
static {
registry.add(new TvdotcomClient());
registry.add(new AnidbClient());
registry.add(new TVRageClient());
}
public static List<EpisodeListClient> getAvailableEpisodeListClients() { public static synchronized List<EpisodeListClient> getAvailableEpisodeListClients() {
if (registry == null) {
registry = new ArrayList<EpisodeListClient>(3);
registry.add(new TvdotcomClient());
registry.add(new AnidbClient());
registry.add(new TVRageClient());
}
return Collections.unmodifiableList(registry); return Collections.unmodifiableList(registry);
} }

View File

@ -2,33 +2,20 @@
package net.sourceforge.filebot.web; package net.sourceforge.filebot.web;
import java.net.URL;
public class MovieDescriptor { public class MovieDescriptor {
private final String title; private final String title;
private final Integer imdbId; private final Integer imdbId;
private final Integer year;
private final URL imdbUrl;
public MovieDescriptor(String title) {
public MovieDescriptor(String description) { this(title, null);
this(description, null);
} }
public MovieDescriptor(String description, Integer imdbId) { public MovieDescriptor(String title, Integer imdbId) {
this(description, imdbId, null, null);
}
public MovieDescriptor(String title, Integer imdbId, Integer year, URL imdbUrl) {
this.title = title; this.title = title;
this.imdbId = imdbId; this.imdbId = imdbId;
this.year = year;
this.imdbUrl = imdbUrl;
} }
@ -42,21 +29,9 @@ public class MovieDescriptor {
} }
public Integer getYear() {
return year;
}
public URL getImdbUrl() {
return imdbUrl;
}
@Override @Override
public String toString() { public String toString() {
if (year == null) return title;
return title;
return String.format("%s (%d)", title, year);
} }
} }

View File

@ -35,9 +35,9 @@ public class OpenSubtitlesClient {
* </tr> * </tr>
* </table> * </table>
*/ */
private String url = "http://www.opensubtitles.org/xml-rpc"; private final String url = "http://www.opensubtitles.org/xml-rpc";
private String useragent; private final String useragent;
private String token = null; private String token = null;
@ -57,6 +57,13 @@ public class OpenSubtitlesClient {
} }
/**
* Login as user and use english as language
*
* @param username
* @param password
* @throws XmlRpcFault
*/
public void login(String username, String password) throws XmlRpcFault { public void login(String username, String password) throws XmlRpcFault {
login(username, password, "en"); login(username, password, "en");
} }
@ -85,19 +92,20 @@ public class OpenSubtitlesClient {
/** /**
* This will logout user (ends session id). Good call this function is before ending * This will logout user (ends session id). Good call this function is before ending
* (closing) clients program. * (closing) clients program.
*
* @throws XmlRpcFault
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public synchronized void logout() { public synchronized void logout() throws XmlRpcFault {
// anonymous users will always get a 401 Unauthorized when trying to logout
try { try {
Map<String, String> response = (Map<String, String>) invoke("LogOut", token); invoke("LogOut", token);
checkStatus(response.get("status"));
} catch (Exception e) { // anonymous users will always get a 401 Unauthorized when trying to logout
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, "Exception while deactivating session", e); // do not check status for logout response
// checkStatus(response.get("status"));
} finally {
token = null;
} }
token = null;
} }

View File

@ -13,7 +13,7 @@ import net.sourceforge.filebot.resources.ResourceManager;
/** /**
* Client for the OpenSubtitles XML-RPC API. * {@link SubtitleClient} for OpenSubtitles.
* *
*/ */
public class OpenSubtitlesSubtitleClient extends SubtitleClient { public class OpenSubtitlesSubtitleClient extends SubtitleClient {
@ -32,7 +32,7 @@ public class OpenSubtitlesSubtitleClient extends SubtitleClient {
@Override @Override
public List<MovieDescriptor> search(String query) throws Exception { public List<MovieDescriptor> search(String query) throws Exception {
activate(); login();
return client.searchMoviesOnIMDB(query); return client.searchMoviesOnIMDB(query);
} }
@ -40,39 +40,45 @@ public class OpenSubtitlesSubtitleClient extends SubtitleClient {
@Override @Override
public List<OpenSubtitlesSubtitleDescriptor> getSubtitleList(MovieDescriptor descriptor) throws Exception { public List<OpenSubtitlesSubtitleDescriptor> getSubtitleList(MovieDescriptor descriptor) throws Exception {
activate(); login();
return client.searchSubtitles(descriptor.getImdbId()); return client.searchSubtitles(descriptor.getImdbId());
} }
private synchronized void activate() { private synchronized void login() throws Exception {
try { if (!client.isLoggedOn()) {
if (!client.isLoggedOn()) { client.loginAnonymous();
client.loginAnonymous();
}
} catch (Exception e) {
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
} }
logoutTimer.restart(); logoutTimer.restart();
} }
private synchronized void logout() {
logoutTimer.stop();
if (client.isLoggedOn()) {
try {
client.logout();
} catch (Exception e) {
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, "Exception while deactivating session", e);
}
}
}
private final Runnable doLogout = new Runnable() { private final Runnable doLogout = new Runnable() {
@Override
public void run() { public void run() {
logoutTimer.stop(); logout();
if (client.isLoggedOn()) {
client.logout();
}
} }
}; };
private class LogoutTimer { private class LogoutTimer {
private static final int LOGOUT_DELAY = 15000; // 12 minutes private final long LOGOUT_DELAY = 12 * 60 * 1000; // 12 minutes
private Timer daemon = null; private Timer daemon = null;
private LogoutTimerTask currentTimerTask = null; private LogoutTimerTask currentTimerTask = null;
@ -85,7 +91,6 @@ public class OpenSubtitlesSubtitleClient extends SubtitleClient {
if (currentTimerTask != null) { if (currentTimerTask != null) {
currentTimerTask.cancel(); currentTimerTask.cancel();
daemon.purge();
} }
currentTimerTask = new LogoutTimerTask(); currentTimerTask = new LogoutTimerTask();
@ -109,7 +114,7 @@ public class OpenSubtitlesSubtitleClient extends SubtitleClient {
@Override @Override
public void run() { public void run() {
doLogout.run(); logout();
}; };
}; };
} }

View File

@ -17,6 +17,7 @@ import java.util.logging.Logger;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import net.sourceforge.filebot.FileFormat;
import net.sourceforge.filebot.resources.ResourceManager; import net.sourceforge.filebot.resources.ResourceManager;
import net.sourceforge.tuned.XPathUtil; import net.sourceforge.tuned.XPathUtil;
@ -71,8 +72,7 @@ public class SubsceneSubtitleClient extends SubtitleClient {
Document dom = HtmlUtil.getHtmlDocument(url); Document dom = HtmlUtil.getHtmlDocument(url);
String downloadPath = XPathUtil.selectString("id('aspnetForm')/@action", dom); Pattern hrefPattern = Pattern.compile("javascript:Subtitle\\((\\d+), '(\\w+)', '0', '(\\d+)'\\);");
String viewstate = XPathUtil.selectString("id('__VIEWSTATE')/@value", dom);
List<Node> nodes = XPathUtil.selectNodes("//TABLE[@class='filmSubtitleList']//A[@id]//ancestor::TR", dom); List<Node> nodes = XPathUtil.selectNodes("//TABLE[@class='filmSubtitleList']//A[@id]//ancestor::TR", dom);
@ -88,15 +88,20 @@ public class SubsceneSubtitleClient extends SubtitleClient {
String name = XPathUtil.selectString("./SPAN[2]", linkNode); String name = XPathUtil.selectString("./SPAN[2]", linkNode);
int numberOfCDs = Integer.parseInt(XPathUtil.selectString("./TD[2]", node)); int numberOfCDs = Integer.parseInt(XPathUtil.selectString("./TD[2]", node));
boolean hearingImpaired = XPathUtil.selectFirstNode("./TD[3]/*[@id='imgEar']", node) != null; boolean hearingImpaired = (XPathUtil.selectFirstNode("./TD[3]/*[@id='imgEar']", node) != null);
String author = XPathUtil.selectString("./TD[4]", node); String author = XPathUtil.selectString("./TD[4]", node);
URL downloadUrl = new URL("http", host, downloadPath); Matcher matcher = hrefPattern.matcher(href);
Map<String, String> downloadParameters = parseParameters(href); if (!matcher.matches())
downloadParameters.put("__VIEWSTATE", viewstate); throw new IllegalArgumentException("Cannot extract download parameters: " + href);
list.add(new SubsceneSubtitleDescriptor(name, lang, numberOfCDs, author, hearingImpaired, downloadUrl, downloadParameters)); String subtitleId = matcher.group(1);
String typeId = matcher.group(2);
URL downloadUrl = getDownloadUrl(url, subtitleId, typeId);
list.add(new SubsceneSubtitleDescriptor(name, lang, numberOfCDs, author, hearingImpaired, typeId, downloadUrl, url));
} catch (Exception e) { } catch (Exception e) {
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.WARNING, "Cannot parse subtitle node", e); Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.WARNING, "Cannot parse subtitle node", e);
} }
@ -106,19 +111,11 @@ public class SubsceneSubtitleClient extends SubtitleClient {
} }
private Map<String, String> parseParameters(String href) { private URL getDownloadUrl(URL referer, String subtitleId, String typeId) throws MalformedURLException {
Matcher matcher = Pattern.compile("javascript:Subtitle\\((\\d+), '(\\w+)', '0', '(\\d+)'\\);").matcher(href); String basePath = FileFormat.getNameWithoutExtension(referer.getFile());
String path = String.format("%s-dlpath-%s/%s.zipx", basePath, subtitleId, typeId);
if (!matcher.matches()) return new URL(referer.getProtocol(), referer.getHost(), path);
throw new IllegalArgumentException("Cannot extract download parameters: " + href);
Map<String, String> map = new HashMap<String, String>();
map.put("subtitleId", matcher.group(1));
map.put("typeId", matcher.group(2));
map.put("filmId", matcher.group(3));
return map;
} }

View File

@ -3,7 +3,6 @@ package net.sourceforge.filebot.web;
import java.net.URL; import java.net.URL;
import java.util.Map;
import net.sourceforge.tuned.DownloadTask; import net.sourceforge.tuned.DownloadTask;
@ -16,19 +15,23 @@ public class SubsceneSubtitleDescriptor implements SubtitleDescriptor {
private final String author; private final String author;
private final boolean hearingImpaired; private final boolean hearingImpaired;
private final Map<String, String> downloadParameters; private final String typeId;
private final URL downloadUrl; private final URL downloadUrl;
private final URL referer;
public SubsceneSubtitleDescriptor(String title, String language, int numberOfCDs, String author, boolean hearingImpaired, URL downloadUrl, Map<String, String> downloadParameters) { public SubsceneSubtitleDescriptor(String title, String language, int numberOfCDs, String author, boolean hearingImpaired, String typeId, URL downloadUrl, URL referer) {
this.title = title; this.title = title;
this.language = language; this.language = language;
this.numberOfCDs = numberOfCDs; this.numberOfCDs = numberOfCDs;
this.author = author; this.author = author;
this.hearingImpaired = hearingImpaired; this.hearingImpaired = hearingImpaired;
this.typeId = typeId;
this.downloadUrl = downloadUrl; this.downloadUrl = downloadUrl;
this.downloadParameters = downloadParameters; this.referer = referer;
} }
@ -60,13 +63,16 @@ public class SubsceneSubtitleDescriptor implements SubtitleDescriptor {
@Override @Override
public DownloadTask createDownloadTask() { public DownloadTask createDownloadTask() {
return new DownloadTask(downloadUrl, downloadParameters); DownloadTask downloadTask = new DownloadTask(downloadUrl);
downloadTask.setRequestHeader("Referer", referer.toString());
return downloadTask;
} }
@Override @Override
public String getArchiveType() { public String getArchiveType() {
return downloadParameters.get("typeId"); return typeId;
} }

View File

@ -11,15 +11,17 @@ import javax.swing.ImageIcon;
public abstract class SubtitleClient { public abstract class SubtitleClient {
private static final List<SubtitleClient> registry = new ArrayList<SubtitleClient>(); private static List<SubtitleClient> registry;
static {
registry.add(new OpenSubtitlesSubtitleClient());
registry.add(new SubsceneSubtitleClient());
}
public static List<SubtitleClient> getAvailableSubtitleClients() { public static synchronized List<SubtitleClient> getAvailableSubtitleClients() {
if (registry == null) {
registry = new ArrayList<SubtitleClient>(2);
registry.add(new OpenSubtitlesSubtitleClient());
registry.add(new SubsceneSubtitleClient());
}
return Collections.unmodifiableList(registry); return Collections.unmodifiableList(registry);
} }

View File

@ -13,6 +13,8 @@ import java.nio.ByteBuffer;
import java.nio.channels.Channels; import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel; import java.nio.channels.WritableByteChannel;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -20,7 +22,7 @@ import java.util.logging.Logger;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
public class DownloadTask extends SwingWorker<ByteBuffer, Object> { public class DownloadTask extends SwingWorker<ByteBuffer, Void> {
public static final String DOWNLOAD_STATE = "download state"; public static final String DOWNLOAD_STATE = "download state";
public static final String DOWNLOAD_PROGRESS = "download progress"; public static final String DOWNLOAD_PROGRESS = "download progress";
@ -30,32 +32,44 @@ public class DownloadTask extends SwingWorker<ByteBuffer, Object> {
PENDING, PENDING,
CONNECTING, CONNECTING,
DOWNLOADING, DOWNLOADING,
DONE; DONE
} }
private static final int BUFFER_SIZE = 4 * 1024; private final int BUFFER_SIZE = 4 * 1024;
private URL url; private URL url;
private ByteBuffer postdata = null; private ByteBuffer postdata;
private long size = -1; private long size = -1;
private long bytesRead = 0; private long bytesRead = 0;
private DownloadState state = DownloadState.PENDING; private DownloadState state = DownloadState.PENDING;
private final Map<String, String> requestHeaders = new HashMap<String, String>();
private final Map<String, String> responseHeaders = new HashMap<String, String>();
public DownloadTask(URL url) { public DownloadTask(URL url) {
this.url = url; this(url, null);
} }
public DownloadTask(URL url, ByteBuffer postdata) { public DownloadTask(URL url, Map<String, String> postParameters) {
this.url = url; this.url = url;
this.postdata = postdata;
if (postParameters != null) {
this.postdata = encodeParameters(postParameters);
}
} }
public DownloadTask(URL url, Map<String, String> postdata) { protected HttpURLConnection createConnection() throws Exception {
this(url, encodeParameters(postdata)); HttpURLConnection connection = (HttpURLConnection) url.openConnection();
for (String key : requestHeaders.keySet()) {
connection.addRequestProperty(key, requestHeaders.get(key));
}
return connection;
} }
@ -63,7 +77,7 @@ public class DownloadTask extends SwingWorker<ByteBuffer, Object> {
protected ByteBuffer doInBackground() throws Exception { protected ByteBuffer doInBackground() throws Exception {
setDownloadState(DownloadState.CONNECTING); setDownloadState(DownloadState.CONNECTING);
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); HttpURLConnection connection = createConnection();
if (postdata != null) { if (postdata != null) {
connection.setRequestMethod("POST"); connection.setRequestMethod("POST");
@ -75,31 +89,39 @@ public class DownloadTask extends SwingWorker<ByteBuffer, Object> {
size = connection.getContentLength(); size = connection.getContentLength();
for (String key : connection.getHeaderFields().keySet()) {
responseHeaders.put(key, connection.getHeaderField(key));
}
setDownloadState(DownloadState.DOWNLOADING); setDownloadState(DownloadState.DOWNLOADING);
InputStream in = connection.getInputStream(); InputStream in = connection.getInputStream();
ByteArrayOutputStream out = new ByteArrayOutputStream(BUFFER_SIZE); ByteArrayOutputStream out = new ByteArrayOutputStream(Math.max((int) size, BUFFER_SIZE));
byte[] buffer = new byte[BUFFER_SIZE]; byte[] buffer = new byte[BUFFER_SIZE];
int len = 0; int len = 0;
try { try {
while (((len = in.read(buffer)) > 0) && !isCancelled()) { while (((len = in.read(buffer)) >= 0) && !isCancelled()) {
out.write(buffer, 0, len); out.write(buffer, 0, len);
bytesRead += len; bytesRead += len;
getPropertyChangeSupport().firePropertyChange(DOWNLOAD_PROGRESS, null, bytesRead);
firePropertyChange(DOWNLOAD_PROGRESS, null, bytesRead);
if (isDownloadSizeKnown()) {
setProgress((int) ((bytesRead * 100) / size));
}
} }
} catch (IOException e) { } catch (IOException e) {
// IOException (Premature EOF) is always thrown when the size of // IOException (Premature EOF) is always thrown when the size of
// the response body is not known in advance, so we ignore it // the response body is not known in advance, so we ignore it
if (isSizeKnown()) if (isDownloadSizeKnown())
throw e; throw e;
} finally { } finally {
in.close(); in.close();
out.close(); out.close();
connection.disconnect();
} }
setDownloadState(DownloadState.DONE); setDownloadState(DownloadState.DONE);
@ -107,9 +129,9 @@ public class DownloadTask extends SwingWorker<ByteBuffer, Object> {
} }
private void setDownloadState(DownloadState state) { protected void setDownloadState(DownloadState state) {
this.state = state; this.state = state;
getPropertyChangeSupport().firePropertyChange(DOWNLOAD_STATE, null, state); firePropertyChange(DOWNLOAD_STATE, null, state);
} }
@ -118,22 +140,37 @@ public class DownloadTask extends SwingWorker<ByteBuffer, Object> {
} }
public URL getUrl() {
return url;
}
public long getBytesRead() { public long getBytesRead() {
return bytesRead; return bytesRead;
} }
public boolean isSizeKnown() { public boolean isDownloadSizeKnown() {
return size >= 0; return size >= 0;
} }
public long getSize() { public long getDownloadSize() {
return size; return size;
} }
private static ByteBuffer encodeParameters(Map<String, String> parameters) { public void setRequestHeader(String name, String value) {
requestHeaders.put(name, value);
}
public Map<String, String> getResponseHeaders() {
return Collections.unmodifiableMap(responseHeaders);
}
protected static ByteBuffer encodeParameters(Map<String, String> parameters) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
int i = 0; int i = 0;

View File

@ -42,8 +42,6 @@ public class TemporaryFolder {
for (TemporaryFolder folder : folders.values()) { for (TemporaryFolder folder : folders.values()) {
folder.delete(); folder.delete();
} }
folders.clear();
} }
} }
}); });
@ -57,6 +55,13 @@ public class TemporaryFolder {
} }
/**
* Create an empty file in this temporary folder
*
* @param name name of the file
* @return newly created file
* @throws IOException if an I/O error occurred
*/
public File createFile(String name) throws IOException { public File createFile(String name) throws IOException {
if (!root.exists()) { if (!root.exists()) {
root.mkdir(); root.mkdir();
@ -69,15 +74,37 @@ public class TemporaryFolder {
} }
public void deleteFile(String name) { /**
File file = new File(root, name); * Creates an empty file in this temporary folder, using the given prefix and suffix to
* generate its name.
if (file.exists()) { *
file.delete(); * @param prefix The prefix string to be used in generating the file's name; must be at
* least three characters long
* @param suffix The suffix string to be used in generating the file's name; may be null,
* in which case the suffix ".tmp" will be used
* @return An abstract pathname denoting a newly-created empty file
* @throws IOException If a file could not be created
* @see File#createTempFile(String, String)
*/
public File createFile(String prefix, String suffix) throws IOException {
if (!root.exists()) {
root.mkdir();
} }
return File.createTempFile(prefix, suffix, root);
} }
public boolean deleteFile(String name) {
return new File(root, name).delete();
}
/**
* Retrieve the {@link File} object for this {@link TemporaryFolder}
*
* @return the {@link File} object for this {@link TemporaryFolder}
*/
public File getFolder() { public File getFolder() {
return root; return root;
} }

View File

@ -1,51 +0,0 @@
package net.sourceforge.tuned;
import java.util.TreeMap;
public class TimeIntervalFormat {
private static TreeMap<Long, String> unitMap = new TreeMap<Long, String>();
static {
unitMap.put(1L, "ms");
unitMap.put(1000L, "s");
unitMap.put(60 * 1000L, "m");
unitMap.put(60 * 60 * 1000L, "h");
}
public static String format(long millis, boolean zerounits) {
boolean negativ = false;
if (millis < 0) {
millis = Math.abs(millis);
negativ = true;
}
StringBuilder sb = new StringBuilder();
for (long unitBaseTime : unitMap.descendingKeySet()) {
int quotient = (int) (millis / unitBaseTime);
boolean isLastKey = (unitBaseTime == unitMap.firstKey());
if (zerounits || (quotient != 0) || isLastKey) {
sb.append(quotient + unitMap.get(unitBaseTime));
if (!isLastKey)
;
sb.append(" ");
}
millis -= quotient * unitBaseTime;
}
if (negativ)
sb.insert(0, "-");
return sb.toString();
}
}

View File

@ -1,6 +1,10 @@
package net.sourceforge.tuned.ui; package net.sourceforge.tuned.ui;
import java.awt.BasicStroke; import java.awt.BasicStroke;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font; import java.awt.Font;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
@ -26,14 +30,15 @@ public class ProgressIndicator extends JComponent {
private int indeterminateShapeCount = 1; private int indeterminateShapeCount = 1;
private float progressStrokeWidth = 4.5f; private float progressStrokeWidth = 4.5f;
private float remainingStrokeWidth = 2.5f; private float remainingStrokeWidth = 2f;
private Stroke progressStroke = new BasicStroke(progressStrokeWidth, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND); private Stroke progressStroke = new BasicStroke(progressStrokeWidth, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND);
private Stroke remainingStroke = new BasicStroke(remainingStrokeWidth, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND); private Stroke remainingStroke = new BasicStroke(remainingStrokeWidth, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND);
private Color progressColor = Color.orange; private Color progressColor = Color.orange;
private Color remainingColor = new Color(0f, 0f, 0f, 0.25f); private Color remainingColor = new Color(0f, 0f, 0f, 0.25f);
private Color textColor = new Color(42, 42, 42);
private Color textColor = new Color(0x5F5F5F);
private boolean paintText = true; private boolean paintText = true;
private boolean paintBackground = false; private boolean paintBackground = false;
@ -42,6 +47,8 @@ public class ProgressIndicator extends JComponent {
private final Arc2D arc = new Arc2D.Double(); private final Arc2D arc = new Arc2D.Double();
private final Ellipse2D circle = new Ellipse2D.Double(); private final Ellipse2D circle = new Ellipse2D.Double();
private final Dimension baseSize = new Dimension(32, 32);
public ProgressIndicator() { public ProgressIndicator() {
this(null); this(null);
@ -53,7 +60,7 @@ public class ProgressIndicator extends JComponent {
indeterminate = (model == null); indeterminate = (model == null);
setFont(new Font(Font.DIALOG, Font.PLAIN, 8)); setFont(new Font(Font.DIALOG, Font.BOLD, 8));
} }
@ -69,20 +76,25 @@ public class ProgressIndicator extends JComponent {
@Override @Override
public void paint(Graphics g) { public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g; Graphics2D g2d = (Graphics2D) g;
double a = Math.min(getWidth(), getHeight());
g2d.scale(a / baseSize.width, a / baseSize.height);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (paintBackground) { if (paintBackground) {
frame.setFrame(0, 0, getWidth(), getHeight()); frame.setFrame(0, 0, baseSize.width, baseSize.height);
g2d.setPaint(getBackground()); g2d.setPaint(getBackground());
circle.setFrame(frame); circle.setFrame(frame);
g2d.fill(circle); g2d.fill(circle);
} }
frame.setFrame(progressStrokeWidth, progressStrokeWidth, getWidth() - progressStrokeWidth * 2 - 1, getHeight() - progressStrokeWidth * 2 - 1); double inset = Math.max(Math.max(remainingStrokeWidth, progressStrokeWidth), indeterminateRadius);
frame.setFrame(inset, inset, baseSize.width - inset * 2 - 1, baseSize.height - inset * 2 - 1);
if (!indeterminate) { if (!indeterminate) {
paintProgress(g2d); paintProgress(g2d);

View File

@ -2,7 +2,6 @@
package net.sourceforge.tuned.ui; package net.sourceforge.tuned.ui;
import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Point; import java.awt.Point;
import java.awt.Window; import java.awt.Window;