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:
parent
12d453eff4
commit
30a54c2cf4
37
build.xml
37
build.xml
|
@ -15,10 +15,16 @@
|
|||
<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.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">
|
||||
<fileset dir="${build}" />
|
||||
|
||||
|
@ -28,38 +34,27 @@
|
|||
<attribute name="Version" value="${version}" />
|
||||
</manifest>
|
||||
|
||||
|
||||
<!-- include libs if fatjar is set -->
|
||||
<zipfileset src="${lib}/${lib.xerces}">
|
||||
<include if="fatjar" name="**/*.class" />
|
||||
<include if="fatjar" name="**/*.properties" />
|
||||
<exclude if="fatjar" name="**/*Test*" />
|
||||
<patternset refid="classes" />
|
||||
</zipfileset>
|
||||
|
||||
<zipfileset src="${lib}/${lib.nekohtml}">
|
||||
<include if="fatjar" name="**/*.class" />
|
||||
<include if="fatjar" name="**/*.properties" />
|
||||
<exclude if="fatjar" name="**/*Test*" />
|
||||
<patternset refid="classes" />
|
||||
</zipfileset>
|
||||
|
||||
<zipfileset src="${lib}/${lib.simmetrics}">
|
||||
<include if="fatjar" name="**/*.class" />
|
||||
<include if="fatjar" name="**/*.properties" />
|
||||
<exclude if="fatjar" name="**/*Test*" />
|
||||
<patternset refid="classes" />
|
||||
</zipfileset>
|
||||
|
||||
<zipfileset src="${lib}/${lib.xmlrpc}">
|
||||
<include if="fatjar" name="**/*.class" />
|
||||
<include if="fatjar" name="**/*.properties" />
|
||||
<exclude if="fatjar" name="**/*Test*" />
|
||||
<patternset refid="classes" />
|
||||
</zipfileset>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
|
||||
<target name="fatjar">
|
||||
<antcall target="jar">
|
||||
<param name="fatjar" value="true" />
|
||||
</antcall>
|
||||
</target>
|
||||
|
||||
|
||||
<target name="build" depends="clean">
|
||||
<!-- create build dir -->
|
||||
<mkdir dir="${build}" />
|
||||
|
|
|
@ -4,7 +4,11 @@ package net.sourceforge.filebot;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.List;
|
||||
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)));
|
||||
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,14 +26,14 @@ public class Settings {
|
|||
public static final String SUBTITLE_HISTORY = "subtitle/history";
|
||||
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() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
private Preferences prefs;
|
||||
private final Preferences prefs;
|
||||
|
||||
|
||||
private Settings() {
|
||||
|
@ -89,7 +89,7 @@ public class Settings {
|
|||
|
||||
|
||||
public void putStringList(String key, Collection<String> list) {
|
||||
Preferences listNode = prefs.node(key);
|
||||
Preferences listNode = getClearNode(key);
|
||||
|
||||
int i = 0;
|
||||
|
||||
|
@ -118,7 +118,7 @@ public class Settings {
|
|||
|
||||
|
||||
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()) {
|
||||
mapNode.put(entry.getKey(), entry.getValue());
|
||||
|
@ -185,10 +185,24 @@ public class Settings {
|
|||
|
||||
public void clear() {
|
||||
try {
|
||||
prefs.removeNode();
|
||||
prefs = Preferences.userRoot().node(ROOT);
|
||||
for (String child : prefs.childrenNames()) {
|
||||
prefs.node(child).removeNode();
|
||||
}
|
||||
} catch (BackingStoreException 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,6 @@ import java.util.Collections;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.ImageIcon;
|
||||
|
@ -30,59 +28,47 @@ public class ResourceManager {
|
|||
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) {
|
||||
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) {
|
||||
if (languageCode == null)
|
||||
languageCode = "default";
|
||||
|
||||
return new ImageIcon(getImage(String.format("flags/%s", languageCode.toLowerCase()), "flags/default"));
|
||||
return getIcon(String.format("flags/%s", languageCode), "flags/default");
|
||||
}
|
||||
|
||||
|
||||
public static ImageIcon getArchiveIcon(String type) {
|
||||
if (type == null)
|
||||
type = "default";
|
||||
|
||||
return new ImageIcon(getImage(String.format("archives/%s", type.toLowerCase()), "archives/default"));
|
||||
return getIcon(String.format("archives/%s", type), "archives/default");
|
||||
}
|
||||
|
||||
|
||||
public static Image getImage(String name) {
|
||||
Image image = cache.get(name);
|
||||
|
||||
if (image == null) {
|
||||
try {
|
||||
// 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);
|
||||
}
|
||||
try {
|
||||
return ImageIO.read(getResource(name));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(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);
|
||||
}
|
||||
|
||||
|
||||
private static URL getResource(String name, String def) {
|
||||
URL resource = getResource(name);
|
||||
|
||||
if (resource == null)
|
||||
resource = getResource(def);
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,35 +22,28 @@ import javax.swing.border.TitledBorder;
|
|||
import net.sourceforge.filebot.ui.transfer.DefaultTransferHandler;
|
||||
import net.sourceforge.filebot.ui.transfer.ExportHandler;
|
||||
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.SaveableExportHandler;
|
||||
import net.sourceforge.filebot.ui.transfer.TransferablePolicyImportHandler;
|
||||
import net.sourceforge.filebot.ui.transfer.TransferablePolicySupport;
|
||||
import net.sourceforge.filebot.ui.transferablepolicies.NullTransferablePolicy;
|
||||
import net.sourceforge.filebot.ui.transferablepolicies.MutableTransferablePolicy;
|
||||
import net.sourceforge.filebot.ui.transferablepolicies.TransferablePolicy;
|
||||
import net.sourceforge.tuned.ui.DefaultFancyListCellRenderer;
|
||||
import net.sourceforge.tuned.ui.SimpleListModel;
|
||||
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 TransferablePolicy transferablePolicy = new NullTransferablePolicy();
|
||||
|
||||
|
||||
public FileBotList(boolean enableDrop, boolean enableDrag, boolean enableRemoveAction) {
|
||||
this(enableDrop, enableDrag, enableRemoveAction, true);
|
||||
}
|
||||
|
||||
|
||||
public FileBotList(boolean enableImport, boolean enableExport, boolean enableRemoveAction, boolean border) {
|
||||
public FileBotList(boolean enableExport, boolean enableRemoveAction, boolean border) {
|
||||
super(new BorderLayout());
|
||||
|
||||
JScrollPane listScrollPane = new JScrollPane(list);
|
||||
|
@ -59,6 +52,7 @@ public class FileBotList extends JPanel implements Saveable, TransferablePolicyS
|
|||
titledBorder = new TitledBorder("");
|
||||
setBorder(titledBorder);
|
||||
} else {
|
||||
titledBorder = null;
|
||||
listScrollPane.setBorder(BorderFactory.createEmptyBorder());
|
||||
}
|
||||
|
||||
|
@ -67,16 +61,12 @@ public class FileBotList extends JPanel implements Saveable, TransferablePolicyS
|
|||
|
||||
add(listScrollPane, BorderLayout.CENTER);
|
||||
|
||||
ImportHandler importHander = null;
|
||||
ExportHandler exportHandler = null;
|
||||
|
||||
if (enableImport)
|
||||
importHander = new TransferablePolicyImportHandler(this);
|
||||
|
||||
if (enableExport)
|
||||
exportHandler = new SaveableExportHandler(this);
|
||||
|
||||
list.setTransferHandler(new DefaultTransferHandler(importHander, exportHandler));
|
||||
list.setTransferHandler(new DefaultTransferHandler(new TransferablePolicyImportHandler(mutableTransferablePolicy), exportHandler));
|
||||
list.setDragEnabled(enableExport);
|
||||
|
||||
if (enableRemoveAction) {
|
||||
|
@ -92,12 +82,12 @@ public class FileBotList extends JPanel implements Saveable, TransferablePolicyS
|
|||
|
||||
|
||||
public void setTransferablePolicy(TransferablePolicy transferablePolicy) {
|
||||
this.transferablePolicy = transferablePolicy;
|
||||
mutableTransferablePolicy.setTransferablePolicy(transferablePolicy);
|
||||
}
|
||||
|
||||
|
||||
public TransferablePolicy getTransferablePolicy() {
|
||||
return transferablePolicy;
|
||||
return mutableTransferablePolicy;
|
||||
}
|
||||
|
||||
|
||||
|
@ -112,10 +102,8 @@ public class FileBotList extends JPanel implements Saveable, TransferablePolicyS
|
|||
if (titledBorder != null)
|
||||
titledBorder.setTitle(title);
|
||||
|
||||
if (isVisible()) {
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
|
@ -153,8 +141,8 @@ public class FileBotList extends JPanel implements Saveable, TransferablePolicyS
|
|||
public void load(List<File> files) {
|
||||
FileTransferable tr = new FileTransferable(files);
|
||||
|
||||
if (transferablePolicy.accept(tr))
|
||||
transferablePolicy.handleTransferable(tr, false);
|
||||
if (mutableTransferablePolicy.accept(tr))
|
||||
mutableTransferablePolicy.handleTransferable(tr, false);
|
||||
}
|
||||
|
||||
private final AbstractAction removeAction = new AbstractAction("Remove") {
|
||||
|
|
|
@ -20,19 +20,21 @@ import net.sourceforge.filebot.ui.panel.subtitle.SubtitlePanel;
|
|||
|
||||
public class FileBotPanel extends JPanel {
|
||||
|
||||
private static final List<FileBotPanel> registry = new ArrayList<FileBotPanel>();
|
||||
|
||||
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());
|
||||
}
|
||||
private static List<FileBotPanel> registry;
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,15 +33,10 @@ class FileBotPanelSelectionList extends JList {
|
|||
|
||||
setBorder(new EmptyBorder(4, 5, 4, 5));
|
||||
|
||||
// initialize "drag over" panel selection
|
||||
new DropTarget(this, new DragDropListener());
|
||||
|
||||
SimpleListModel model = new SimpleListModel();
|
||||
|
||||
for (FileBotPanel panel : FileBotPanel.getAvailablePanels()) {
|
||||
model.add(panel);
|
||||
}
|
||||
|
||||
setModel(model);
|
||||
setModel(new SimpleListModel(FileBotPanel.getAvailablePanels()));
|
||||
}
|
||||
|
||||
|
||||
|
@ -110,6 +105,7 @@ class FileBotPanelSelectionList extends JList {
|
|||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void drop(DropTargetDropEvent dtde) {
|
||||
|
||||
}
|
||||
|
|
|
@ -4,42 +4,30 @@ package net.sourceforge.filebot.ui;
|
|||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import net.sourceforge.filebot.resources.ResourceManager;
|
||||
|
||||
|
||||
public class FileBotTabComponent extends JPanel {
|
||||
|
||||
private final JLabel label;
|
||||
private final JLabel label = new JLabel();
|
||||
private final JButton closeButton = createCloseButton();
|
||||
|
||||
|
||||
public FileBotTabComponent() {
|
||||
this("", null);
|
||||
}
|
||||
|
||||
|
||||
public FileBotTabComponent(String title, Icon icon) {
|
||||
super(new BorderLayout(0, 0));
|
||||
setOpaque(false);
|
||||
|
||||
label = new JLabel(title, SwingConstants.LEFT);
|
||||
label.setIcon(icon);
|
||||
|
||||
label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 2));
|
||||
|
||||
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() {
|
||||
JTabbedPane tabs = (JTabbedPane) SwingUtilities.getAncestorOfClass(JTabbedPane.class, FileBotTabComponent.this);
|
||||
tabs.removeTabAt(tabs.indexOfTabComponent(FileBotTabComponent.this));
|
||||
public JButton getCloseButton() {
|
||||
return closeButton;
|
||||
}
|
||||
|
||||
private final AbstractAction tabCloseAction = new AbstractAction(null, null) {
|
||||
|
||||
private JButton createCloseButton() {
|
||||
JButton button = new JButton();
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
close();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private class CloseButton extends JButton {
|
||||
button.setContentAreaFilled(false);
|
||||
button.setBorderPainted(false);
|
||||
button.setFocusable(false);
|
||||
button.setRolloverEnabled(true);
|
||||
|
||||
public CloseButton(AbstractAction action) {
|
||||
super(action);
|
||||
|
||||
setContentAreaFilled(false);
|
||||
setBorderPainted(false);
|
||||
setFocusable(false);
|
||||
|
||||
setIcon(ResourceManager.getIcon("tab.close"));
|
||||
setRolloverIcon(ResourceManager.getIcon("tab.close.hover"));
|
||||
setRolloverEnabled(true);
|
||||
|
||||
setPreferredSize(new Dimension(17, 17));
|
||||
}
|
||||
};
|
||||
button.setIcon(ResourceManager.getIcon("tab.close"));
|
||||
button.setRolloverIcon(ResourceManager.getIcon("tab.close.hover"));
|
||||
|
||||
button.setPreferredSize(new Dimension(17, 17));
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,15 +26,9 @@ import javax.swing.tree.TreePath;
|
|||
import javax.swing.tree.TreeSelectionModel;
|
||||
|
||||
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 {
|
||||
|
||||
private TransferablePolicy transferablePolicy = new NullTransferablePolicy();
|
||||
|
||||
public class FileBotTree extends JTree {
|
||||
|
||||
public FileBotTree() {
|
||||
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() {
|
||||
TreeNode node = (TreeNode) getModel().getRoot();
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import java.util.logging.Level;
|
|||
import java.util.logging.Logger;
|
||||
|
||||
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.MessageHandler;
|
||||
|
||||
|
@ -18,18 +18,17 @@ import net.sourceforge.tuned.MessageHandler;
|
|||
public class FileTransferableMessageHandler implements MessageHandler {
|
||||
|
||||
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.transferablePolicySupport = transferablePolicySupport;
|
||||
this.transferablePolicy = transferablePolicy;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void handle(String topic, String... messages) {
|
||||
|
||||
// change panel
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ public class AnalyzePanel extends FileBotPanel {
|
|||
|
||||
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()));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import net.sourceforge.filebot.ui.FileBotTree;
|
|||
import net.sourceforge.filebot.ui.transfer.DefaultTransferHandler;
|
||||
import net.sourceforge.filebot.ui.transfer.FileTransferable;
|
||||
import net.sourceforge.filebot.ui.transfer.TransferablePolicyImportHandler;
|
||||
import net.sourceforge.filebot.ui.transferablepolicies.TransferablePolicy;
|
||||
|
||||
|
||||
class FileTree extends FileBotTree {
|
||||
|
@ -29,13 +30,19 @@ class FileTree extends FileBotTree {
|
|||
|
||||
private PostProcessor postProcessor;
|
||||
|
||||
private final FileTreeTransferablePolicy transferablePolicy;
|
||||
|
||||
|
||||
public FileTree() {
|
||||
FileTreeTransferablePolicy transferPolicy = new FileTreeTransferablePolicy(this);
|
||||
transferPolicy.addPropertyChangeListener(LOADING_PROPERTY, new LoadingPropertyChangeListener());
|
||||
transferablePolicy = new FileTreeTransferablePolicy(this);
|
||||
transferablePolicy.addPropertyChangeListener(LOADING_PROPERTY, new LoadingPropertyChangeListener());
|
||||
|
||||
setTransferablePolicy(transferPolicy);
|
||||
setTransferHandler(new DefaultTransferHandler(new TransferablePolicyImportHandler(this), null));
|
||||
setTransferHandler(new DefaultTransferHandler(new TransferablePolicyImportHandler(transferablePolicy), null));
|
||||
}
|
||||
|
||||
|
||||
public TransferablePolicy getTransferablePolicy() {
|
||||
return transferablePolicy;
|
||||
}
|
||||
|
||||
|
||||
|
@ -64,14 +71,14 @@ class FileTree extends FileBotTree {
|
|||
public void load(List<File> files) {
|
||||
FileTransferable tr = new FileTransferable(files);
|
||||
|
||||
if (getTransferablePolicy().accept(tr))
|
||||
getTransferablePolicy().handleTransferable(tr, true);
|
||||
if (transferablePolicy.accept(tr))
|
||||
transferablePolicy.handleTransferable(tr, true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
((FileTreeTransferablePolicy) getTransferablePolicy()).reset();
|
||||
transferablePolicy.reset();
|
||||
|
||||
super.clear();
|
||||
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
|
||||
protected List<File> doInBackground() throws Exception {
|
||||
|
|
|
@ -50,7 +50,7 @@ class FileTreePanel extends JPanel {
|
|||
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")) {
|
||||
|
||||
|
|
|
@ -22,12 +22,6 @@ class FileTreeTransferablePolicy extends BackgroundFileTransferablePolicy<Defaul
|
|||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean accept(File file) {
|
||||
return file.isFile() || file.isDirectory();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void clear() {
|
||||
tree.clear();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -26,12 +26,6 @@ class FileListTransferablePolicy extends FileTransferablePolicy {
|
|||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean accept(File file) {
|
||||
return file.isFile() || file.isDirectory();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void clear() {
|
||||
list.getModel().clear();
|
||||
|
|
|
@ -39,7 +39,7 @@ public class ListPanel extends FileBotPanel {
|
|||
private FileBotList list = new FileBotList(true, true, true);
|
||||
|
||||
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 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);
|
||||
|
||||
MessageBus.getDefault().addMessageHandler(getPanelName(), new FileTransferableMessageHandler(getPanelName(), list));
|
||||
MessageBus.getDefault().addMessageHandler(getPanelName(), new FileTransferableMessageHandler(getPanelName(), list.getTransferablePolicy()));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -22,12 +22,6 @@ class FilesListTransferablePolicy extends FileTransferablePolicy {
|
|||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean accept(File file) {
|
||||
return file.isFile() || file.isDirectory();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void clear() {
|
||||
model.clear();
|
||||
|
|
|
@ -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 secondaryList;
|
||||
|
|
|
@ -69,12 +69,6 @@ class NamesListTransferablePolicy extends MultiTransferablePolicy {
|
|||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean accept(File file) {
|
||||
return file.isFile() || file.isDirectory();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void load(List<File> files) {
|
||||
|
||||
|
@ -146,7 +140,7 @@ class NamesListTransferablePolicy extends MultiTransferablePolicy {
|
|||
protected void load(String text) {
|
||||
List<ListEntry> entries = new ArrayList<ListEntry>();
|
||||
|
||||
String[] lines = text.split("\n");
|
||||
String[] lines = text.split("\r?\n");
|
||||
|
||||
for (String line : lines) {
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ import net.sourceforge.filebot.ui.transfer.LoadAction;
|
|||
class RenameList extends FileBotList {
|
||||
|
||||
public RenameList() {
|
||||
super(true, false, true);
|
||||
super(false, true, true);
|
||||
|
||||
Box buttons = Box.createHorizontalBox();
|
||||
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() {
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package net.sourceforge.filebot.ui.panel.search;
|
|||
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JComponent;
|
||||
|
||||
import net.sourceforge.filebot.resources.ResourceManager;
|
||||
import net.sourceforge.filebot.ui.FileBotList;
|
||||
|
@ -19,11 +20,11 @@ public class EpisodeListPanel extends FileBotList {
|
|||
|
||||
|
||||
public EpisodeListPanel() {
|
||||
super(false, true, true, false);
|
||||
super(true, true, false);
|
||||
}
|
||||
|
||||
|
||||
public FileBotTabComponent getTabComponent() {
|
||||
public JComponent getTabComponent() {
|
||||
return tabComponent;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import net.sourceforge.filebot.web.Episode;
|
|||
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 EpisodeListClient searchEngine;
|
||||
|
|
|
@ -8,7 +8,6 @@ import java.awt.Window;
|
|||
import java.awt.event.ActionEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.ArrayList;
|
||||
|
@ -181,41 +180,20 @@ public class SearchPanel extends FileBotPanel {
|
|||
|
||||
private final SaveAction saveAction = new SaveAction(null) {
|
||||
|
||||
private Saveable current;
|
||||
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Component c = tabbedPane.getSelectedComponent();
|
||||
|
||||
if (c instanceof Saveable) {
|
||||
current = (Saveable) c;
|
||||
setSaveable((Saveable) c);
|
||||
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 EpisodeListClient client;
|
||||
|
|
|
@ -10,7 +10,7 @@ import java.util.zip.CheckedInputStream;
|
|||
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;
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ public class SfvPanel extends FileBotPanel {
|
|||
// Shortcut DELETE
|
||||
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) {
|
||||
|
@ -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")) {
|
||||
|
||||
|
|
|
@ -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.renderer.ChecksumTableCellRenderer;
|
||||
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.ExportHandler;
|
||||
import net.sourceforge.filebot.ui.transfer.ImportHandler;
|
||||
import net.sourceforge.filebot.ui.transfer.Saveable;
|
||||
import net.sourceforge.filebot.ui.transfer.SaveableExportHandler;
|
||||
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;
|
||||
|
||||
|
||||
class SfvTable extends JTable implements TransferablePolicySupport, Saveable {
|
||||
class SfvTable extends JTable implements Saveable {
|
||||
|
||||
private TransferablePolicy transferablePolicy = new NullTransferablePolicy();
|
||||
private final SfvTransferablePolicy transferablePolicy;
|
||||
|
||||
|
||||
public SfvTable() {
|
||||
final ChecksumTableModel model = (ChecksumTableModel) getModel();
|
||||
|
||||
setFillsViewportHeight(true);
|
||||
ChecksumTableModel model = (ChecksumTableModel) getModel();
|
||||
|
||||
transferablePolicy = new SfvTransferablePolicy(model);
|
||||
|
||||
setModel(model);
|
||||
|
||||
setFillsViewportHeight(true);
|
||||
setAutoCreateRowSorter(true);
|
||||
setAutoCreateColumnsFromModel(true);
|
||||
setAutoResizeMode(AUTO_RESIZE_SUBSEQUENT_COLUMNS);
|
||||
|
@ -54,18 +50,22 @@ class SfvTable extends JTable implements TransferablePolicySupport, Saveable {
|
|||
|
||||
setRowHeight(20);
|
||||
|
||||
ImportHandler importHandler = new TransferablePolicyImportHandler(this);
|
||||
ImportHandler importHandler = new TransferablePolicyImportHandler(transferablePolicy);
|
||||
ExportHandler exportHandler = new SaveableExportHandler(this);
|
||||
|
||||
setTransferHandler(new DefaultTransferHandler(importHandler, exportHandler));
|
||||
setDragEnabled(true);
|
||||
|
||||
setDefaultRenderer(ChecksumRow.State.class, new StateIconTableCellRenderer());
|
||||
setDefaultRenderer(String.class, new TextTableCellRenderer());
|
||||
setDefaultRenderer(Checksum.class, new ChecksumTableCellRenderer());
|
||||
}
|
||||
|
||||
|
||||
public TransferablePolicy getTransferablePolicy() {
|
||||
return transferablePolicy;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected TableModel createDefaultDataModel() {
|
||||
return new ChecksumTableModel();
|
||||
|
@ -90,22 +90,12 @@ class SfvTable extends JTable implements TransferablePolicySupport, Saveable {
|
|||
|
||||
|
||||
public void clear() {
|
||||
((BackgroundFileTransferablePolicy<?>) getTransferablePolicy()).reset();
|
||||
transferablePolicy.reset();
|
||||
|
||||
((ChecksumTableModel) getModel()).clear();
|
||||
}
|
||||
|
||||
|
||||
public TransferablePolicy getTransferablePolicy() {
|
||||
return transferablePolicy;
|
||||
}
|
||||
|
||||
|
||||
public void setTransferablePolicy(TransferablePolicy transferablePolicy) {
|
||||
this.transferablePolicy = transferablePolicy;
|
||||
}
|
||||
|
||||
|
||||
public String getDefaultFileName() {
|
||||
ChecksumTableModel model = (ChecksumTableModel) getModel();
|
||||
File columnRoot = model.getChecksumColumnRoot(0);
|
||||
|
|
|
@ -27,12 +27,6 @@ class SfvTransferablePolicy extends BackgroundFileTransferablePolicy<ChecksumTab
|
|||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean accept(File file) {
|
||||
return file.isFile() || file.isDirectory();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void clear() {
|
||||
tableModel.clear();
|
||||
|
|
|
@ -5,13 +5,14 @@ package net.sourceforge.filebot.ui.panel.sfv.renderer;
|
|||
import java.awt.Component;
|
||||
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
|
||||
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
|
||||
|
|
|
@ -6,10 +6,10 @@ import java.awt.BorderLayout;
|
|||
import java.awt.Component;
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JProgressBar;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
|
||||
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 {
|
||||
|
||||
private JProgressBar progressBar = new JProgressBar(0, 100);
|
||||
private final JProgressBar progressBar = new JProgressBar(0, 100);
|
||||
|
||||
|
||||
public ProgressBarTableCellRenderer() {
|
||||
super(new BorderLayout());
|
||||
|
||||
progressBar.setStringPainted(true);
|
||||
|
||||
add(progressBar, BorderLayout.CENTER);
|
||||
|
||||
int margin = 2;
|
||||
setBorder(BorderFactory.createEmptyBorder(margin, margin, margin, margin));
|
||||
setBorder(new EmptyBorder(2, 2, 2, 2));
|
||||
}
|
||||
|
||||
|
||||
|
@ -50,6 +50,7 @@ public class ProgressBarTableCellRenderer extends JPanel implements TableCellRen
|
|||
/**
|
||||
* Overridden for performance reasons.
|
||||
*/
|
||||
@Override
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
public void repaint(Rectangle r) {
|
||||
}
|
||||
|
||||
|
@ -64,6 +66,7 @@ public class ProgressBarTableCellRenderer extends JPanel implements TableCellRen
|
|||
/**
|
||||
* Overridden for performance reasons.
|
||||
*/
|
||||
@Override
|
||||
public void repaint() {
|
||||
}
|
||||
|
||||
|
@ -71,6 +74,7 @@ public class ProgressBarTableCellRenderer extends JPanel implements TableCellRen
|
|||
/**
|
||||
* Overridden for performance reasons.
|
||||
*/
|
||||
@Override
|
||||
public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {
|
||||
}
|
||||
|
||||
|
|
|
@ -7,13 +7,14 @@ import java.awt.Component;
|
|||
import javax.swing.Icon;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
|
||||
import net.sourceforge.filebot.resources.ResourceManager;
|
||||
import net.sourceforge.filebot.ui.panel.sfv.ChecksumRow;
|
||||
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 error = ResourceManager.getIcon("status.error");
|
||||
|
@ -46,8 +47,6 @@ public class StateIconTableCellRenderer extends TextTableCellRenderer {
|
|||
case UNKNOWN:
|
||||
setIcon(unknown);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return this;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -20,4 +20,9 @@ public enum ArchiveType {
|
|||
return UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
public String getExtension() {
|
||||
return toString().toLowerCase();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import net.sourceforge.filebot.web.SubtitleClient;
|
|||
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 MovieDescriptor descriptor;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
|
@ -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
|
||||
* @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) {
|
||||
for (Locale locale : Locale.getAvailableLocales()) {
|
||||
if (locale.getDisplayLanguage(Locale.ENGLISH).toLowerCase().equals(languageName))
|
||||
|
|
|
@ -12,8 +12,6 @@ import javax.swing.JLabel;
|
|||
import javax.swing.JList;
|
||||
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.IconViewCellRenderer;
|
||||
|
||||
|
@ -44,18 +42,17 @@ public class SubtitleCellRenderer extends IconViewCellRenderer {
|
|||
public void configureListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
super.configureListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||
|
||||
SubtitleDescriptor subtitle = (SubtitleDescriptor) value;
|
||||
SubtitlePackage subtitle = (SubtitlePackage) value;
|
||||
|
||||
setText(subtitle.getName());
|
||||
|
||||
info1.setText(subtitle.getLanguageName());
|
||||
info2.setText(subtitle.getAuthor());
|
||||
|
||||
icon = (ResourceManager.getFlagIcon(LanguageResolver.getDefault().getLocale(subtitle.getLanguageName()).getLanguage()));
|
||||
icon = subtitle.getLanguageIcon();
|
||||
|
||||
info1.setIcon(icon);
|
||||
|
||||
ImageIcon icon = ResourceManager.getArchiveIcon(subtitle.getArchiveType());
|
||||
ImageIcon icon = subtitle.getArchiveIcon();
|
||||
|
||||
if (isSelected) {
|
||||
setIcon(new ImageIcon(createImage(new FilteredImageSource(icon.getImage().getSource(), new ColorTintImageFilter(list.getSelectionBackground(), 0.5f)))));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -6,7 +6,7 @@ import java.beans.PropertyChangeEvent;
|
|||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
|
||||
import net.sourceforge.filebot.resources.ResourceManager;
|
||||
import net.sourceforge.filebot.web.SubtitleDescriptor;
|
||||
|
@ -17,13 +17,20 @@ public class SubtitlePackage {
|
|||
|
||||
private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
|
||||
|
||||
private DownloadTask downloadTask = null;
|
||||
|
||||
private final SubtitleDescriptor subtitleDescriptor;
|
||||
|
||||
private final ImageIcon archiveIcon;
|
||||
|
||||
private final ImageIcon languageIcon;
|
||||
|
||||
private DownloadTask downloadTask;
|
||||
|
||||
|
||||
public SubtitlePackage(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() {
|
||||
return ResourceManager.getArchiveIcon(getArchiveType().toString());
|
||||
public ImageIcon getArchiveIcon() {
|
||||
return archiveIcon;
|
||||
}
|
||||
|
||||
|
||||
|
@ -47,8 +54,8 @@ public class SubtitlePackage {
|
|||
}
|
||||
|
||||
|
||||
public Icon getLanguageIcon() {
|
||||
return ResourceManager.getFlagIcon(LanguageResolver.getDefault().getLanguageCode(getLanguageName()));
|
||||
public ImageIcon getLanguageIcon() {
|
||||
return languageIcon;
|
||||
}
|
||||
|
||||
|
||||
|
@ -57,7 +64,7 @@ public class SubtitlePackage {
|
|||
throw new IllegalStateException("Download has been started already");
|
||||
|
||||
downloadTask = subtitleDescriptor.createDownloadTask();
|
||||
downloadTask.addPropertyChangeListener(new DownloadTaskPropertyChangeRelay());
|
||||
downloadTask.addPropertyChangeListener(new DownloadTaskPropertyChangeAdapter());
|
||||
|
||||
downloadTask.execute();
|
||||
}
|
||||
|
@ -81,7 +88,7 @@ public class SubtitlePackage {
|
|||
}
|
||||
|
||||
|
||||
private class DownloadTaskPropertyChangeRelay implements PropertyChangeListener {
|
||||
private class DownloadTaskPropertyChangeAdapter implements PropertyChangeListener {
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
|
|
|
@ -20,25 +20,23 @@ import java.util.TreeSet;
|
|||
import javax.swing.Icon;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JToggleButton;
|
||||
import javax.swing.JToolTip;
|
||||
import javax.swing.ListModel;
|
||||
|
||||
import net.sourceforge.filebot.Settings;
|
||||
import net.sourceforge.filebot.resources.ResourceManager;
|
||||
import net.sourceforge.filebot.web.SubtitleDescriptor;
|
||||
import net.sourceforge.tuned.ui.IconViewPanel;
|
||||
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 JPanel languageFilterPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 1));
|
||||
|
||||
private Map<String, Boolean> languageFilterSelection = new TreeMap<String, Boolean>(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
|
||||
public SubtitleViewPanel() {
|
||||
public SubtitlePackagePanel() {
|
||||
setCellRenderer(new SubtitleCellRenderer());
|
||||
|
||||
languageFilterPanel.setOpaque(false);
|
||||
|
@ -71,7 +69,7 @@ public class SubtitleViewPanel extends IconViewPanel {
|
|||
SortedSet<String> languages = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
for (int i = 0; i < unfilteredModel.getSize(); i++) {
|
||||
SubtitleDescriptor subtitle = (SubtitleDescriptor) unfilteredModel.getElementAt(i);
|
||||
SubtitlePackage subtitle = (SubtitlePackage) unfilteredModel.getElementAt(i);
|
||||
languages.add(subtitle.getLanguageName());
|
||||
}
|
||||
|
||||
|
@ -90,7 +88,7 @@ public class SubtitleViewPanel extends IconViewPanel {
|
|||
SimpleListModel model = new SimpleListModel();
|
||||
|
||||
for (int i = 0; i < unfilteredModel.getSize(); i++) {
|
||||
SubtitleDescriptor subtitle = (SubtitleDescriptor) unfilteredModel.getElementAt(i);
|
||||
SubtitlePackage subtitle = (SubtitlePackage) unfilteredModel.getElementAt(i);
|
||||
|
||||
if (isLanguageSelected(subtitle.getLanguageName())) {
|
||||
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) {
|
||||
Locale locale = LanguageResolver.getDefault().getLocale(language);
|
||||
|
||||
|
@ -132,8 +136,7 @@ public class SubtitleViewPanel extends IconViewPanel {
|
|||
public void itemStateChanged(ItemEvent e) {
|
||||
boolean selected = (e.getStateChange() == ItemEvent.SELECTED);
|
||||
|
||||
languageFilterSelection.put(language, selected);
|
||||
Settings.getSettings().putBooleanMapEntry(Settings.SUBTITLE_LANGUAGE, language, selected);
|
||||
setLanguageSelected(language, selected);
|
||||
|
||||
updateFilteredModel();
|
||||
}
|
||||
|
@ -170,19 +173,15 @@ public class SubtitleViewPanel extends IconViewPanel {
|
|||
protected void paintComponent(Graphics g) {
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
|
||||
AlphaComposite composite = AlphaComposite.SrcOver.derive(isSelected() ? 1.0f : 0.2f);
|
||||
g2d.setComposite(composite);
|
||||
// make transparent if not selected
|
||||
if (!isSelected()) {
|
||||
AlphaComposite composite = AlphaComposite.SrcOver.derive(0.2f);
|
||||
g2d.setComposite(composite);
|
||||
}
|
||||
|
||||
super.paintComponent(g2d);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public JToolTip createToolTip() {
|
||||
System.out.println("SubtitleViewPanel.createToolTip()");
|
||||
return super.createToolTip();
|
||||
}
|
||||
|
||||
}
|
|
@ -30,7 +30,6 @@ import net.sourceforge.filebot.FileBotUtil;
|
|||
import net.sourceforge.filebot.Settings;
|
||||
import net.sourceforge.filebot.resources.ResourceManager;
|
||||
import net.sourceforge.filebot.ui.FileBotPanel;
|
||||
import net.sourceforge.filebot.ui.FileBotTabComponent;
|
||||
import net.sourceforge.filebot.ui.HistoryPanel;
|
||||
import net.sourceforge.filebot.ui.MessageManager;
|
||||
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 SubtitleClient client;
|
||||
|
@ -155,26 +154,27 @@ public class SubtitlePanel extends FileBotPanel {
|
|||
|
||||
private class SearchTaskListener extends SwingWorkerPropertyChangeAdapter {
|
||||
|
||||
private SubtitleViewPanel subtitleSearchResultPanel;
|
||||
private FileBotTabComponent tabComponent;
|
||||
private FileBotTab<SubtitleDownloadPanel> downloadPanel;
|
||||
|
||||
|
||||
@Override
|
||||
public void started(PropertyChangeEvent evt) {
|
||||
SearchTask task = (SearchTask) evt.getSource();
|
||||
|
||||
subtitleSearchResultPanel = new SubtitleViewPanel();
|
||||
tabComponent = new FileBotTabComponent(task.query, ResourceManager.getIcon("tab.loading"));
|
||||
downloadPanel = new FileBotTab<SubtitleDownloadPanel>(new SubtitleDownloadPanel());
|
||||
|
||||
tabbedPane.addTab(task.query, subtitleSearchResultPanel);
|
||||
tabbedPane.setTabComponentAt(tabbedPane.indexOfComponent(subtitleSearchResultPanel), tabComponent);
|
||||
downloadPanel.setTitle(task.query);
|
||||
downloadPanel.setLoading(true);
|
||||
downloadPanel.setIcon(task.client.getIcon());
|
||||
|
||||
downloadPanel.addTo(tabbedPane);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void done(PropertyChangeEvent evt) {
|
||||
// tab might have been closed
|
||||
if (tabbedPane.indexOfComponent(subtitleSearchResultPanel) < 0)
|
||||
if (downloadPanel.isClosed())
|
||||
return;
|
||||
|
||||
SearchTask searchTask = (SearchTask) evt.getSource();
|
||||
|
@ -185,18 +185,26 @@ public class SubtitlePanel extends FileBotPanel {
|
|||
MovieDescriptor descriptor = selectDescriptor(desriptors, searchTask.client);
|
||||
|
||||
if (descriptor == null) {
|
||||
// user canceled selection, or no subtitles available
|
||||
if (desriptors.isEmpty()) {
|
||||
MessageManager.showWarning(String.format("\"%s\" has not been found.", searchTask.query));
|
||||
}
|
||||
|
||||
tabbedPane.remove(subtitleSearchResultPanel);
|
||||
downloadPanel.close();
|
||||
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) {
|
||||
tabbedPane.remove(subtitleSearchResultPanel);
|
||||
downloadPanel.close();
|
||||
|
||||
Throwable cause = FileBotUtil.getRootCause(e);
|
||||
|
||||
|
@ -224,42 +232,27 @@ public class SubtitlePanel extends FileBotPanel {
|
|||
selectDialog.setIconImage(client.getIcon().getImage());
|
||||
selectDialog.setVisible(true);
|
||||
|
||||
// selected value or null if cancelled by the user
|
||||
// selected value or null if canceled by the user
|
||||
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 final SubtitleViewPanel subtitleSearchResultPanel;
|
||||
private final FileBotTabComponent tabComponent;
|
||||
private final FileBotTab<SubtitleDownloadPanel> downloadPanel;
|
||||
|
||||
|
||||
public FetchSubtitleListTaskListener(SubtitleViewPanel subtitleSearchResultPanel, FileBotTabComponent tabComponent) {
|
||||
this.subtitleSearchResultPanel = subtitleSearchResultPanel;
|
||||
this.tabComponent = tabComponent;
|
||||
public FetchSubtitleListTaskListener(FileBotTab<SubtitleDownloadPanel> downloadPanel) {
|
||||
this.downloadPanel = downloadPanel;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void done(PropertyChangeEvent evt) {
|
||||
// tab might have been closed
|
||||
if (tabbedPane.indexOfComponent(subtitleSearchResultPanel) < 0)
|
||||
if (downloadPanel.isClosed())
|
||||
return;
|
||||
|
||||
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");
|
||||
|
||||
if (subtitleDescriptors.isEmpty()) {
|
||||
tabbedPane.remove(subtitleSearchResultPanel);
|
||||
MessageManager.showWarning(info);
|
||||
downloadPanel.close();
|
||||
return;
|
||||
}
|
||||
|
||||
tabComponent.setIcon(task.getClient().getIcon());
|
||||
downloadPanel.setLoading(false);
|
||||
|
||||
//TODO icon view
|
||||
//TODO sysout
|
||||
System.out.println(subtitleDescriptors);
|
||||
downloadPanel.getComponent().getPackagePanel().setTitle(info);
|
||||
downloadPanel.getComponent().addSubtitleDescriptors(subtitleDescriptors);
|
||||
} catch (Exception e) {
|
||||
tabbedPane.remove(subtitleSearchResultPanel);
|
||||
downloadPanel.close();
|
||||
|
||||
MessageManager.showWarning(FileBotUtil.getRootCause(e).getMessage());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
|
|
|
@ -20,12 +20,12 @@ public class Unrar {
|
|||
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) {
|
||||
throw new IllegalStateException("Unrar could not be initialized");
|
||||
}
|
||||
|
||||
Process process = command.execute(archive, destination);
|
||||
Process process = command.execute(archiveFile, destinationFolder);
|
||||
|
||||
int counter = 0;
|
||||
|
||||
|
@ -117,7 +117,15 @@ public class Unrar {
|
|||
ProcessBuilder builder = new ProcessBuilder(executable, "x", "-y", archive.getAbsolutePath());
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -92,5 +92,26 @@ public class DefaultTransferHandler extends TransferHandler {
|
|||
if (clipboardHandler != null)
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -13,19 +13,19 @@ import net.sourceforge.filebot.ui.transferablepolicies.TransferablePolicy;
|
|||
|
||||
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"));
|
||||
this.transferablePolicySupport = transferablePolicySupport;
|
||||
this.transferablePolicy = transferablePolicy;
|
||||
}
|
||||
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
|
||||
chooser.setFileFilter(new TransferablePolicyFileFilter(transferablePolicySupport.getTransferablePolicy()));
|
||||
chooser.setFileFilter(new TransferablePolicyFileFilter(transferablePolicy));
|
||||
|
||||
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
|
||||
chooser.setMultiSelectionEnabled(true);
|
||||
|
@ -35,8 +35,6 @@ public class LoadAction extends AbstractAction {
|
|||
|
||||
FileTransferable transferable = new FileTransferable(chooser.getSelectedFiles());
|
||||
|
||||
TransferablePolicy transferablePolicy = transferablePolicySupport.getTransferablePolicy();
|
||||
|
||||
boolean add = ((e.getModifiers() & ActionEvent.CTRL_MASK) != 0);
|
||||
|
||||
if (transferablePolicy.accept(transferable))
|
||||
|
|
|
@ -43,6 +43,11 @@ public class SaveAction extends AbstractAction {
|
|||
}
|
||||
|
||||
|
||||
protected void setSaveable(Saveable saveable) {
|
||||
this.saveable = saveable;
|
||||
}
|
||||
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (!isSaveable())
|
||||
return;
|
||||
|
|
|
@ -13,7 +13,7 @@ import net.sourceforge.filebot.ui.transferablepolicies.TransferablePolicy;
|
|||
|
||||
public class TransferablePolicyFileFilter extends FileFilter {
|
||||
|
||||
private TransferablePolicy transferablePolicy;
|
||||
private final TransferablePolicy transferablePolicy;
|
||||
|
||||
|
||||
public TransferablePolicyFileFilter(TransferablePolicy transferablePolicy) {
|
||||
|
|
|
@ -10,15 +10,16 @@ import java.util.logging.Logger;
|
|||
import javax.swing.TransferHandler;
|
||||
import javax.swing.TransferHandler.TransferSupport;
|
||||
|
||||
import net.sourceforge.filebot.ui.transferablepolicies.TransferablePolicy;
|
||||
|
||||
|
||||
public class TransferablePolicyImportHandler implements ImportHandler {
|
||||
|
||||
private TransferablePolicySupport transferablePolicySupport;
|
||||
private final TransferablePolicy transferablePolicy;
|
||||
|
||||
|
||||
public TransferablePolicyImportHandler(TransferablePolicySupport transferablePolicySupport) {
|
||||
this.transferablePolicySupport = transferablePolicySupport;
|
||||
public TransferablePolicyImportHandler(TransferablePolicy transferablePolicy) {
|
||||
this.transferablePolicy = transferablePolicy;
|
||||
}
|
||||
|
||||
private boolean canImportCache = false;
|
||||
|
@ -32,7 +33,7 @@ public class TransferablePolicyImportHandler implements ImportHandler {
|
|||
Transferable t = support.getTransferable();
|
||||
|
||||
try {
|
||||
canImportCache = transferablePolicySupport.getTransferablePolicy().accept(t);
|
||||
canImportCache = transferablePolicy.accept(t);
|
||||
} catch (InvalidDnDOperationException e) {
|
||||
// for some reason the last transferable has no drop current
|
||||
}
|
||||
|
@ -51,7 +52,7 @@ public class TransferablePolicyImportHandler implements ImportHandler {
|
|||
Transferable t = support.getTransferable();
|
||||
|
||||
try {
|
||||
transferablePolicySupport.getTransferablePolicy().handleTransferable(t, add);
|
||||
transferablePolicy.handleTransferable(t, add);
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
|
||||
package net.sourceforge.filebot.ui.transfer;
|
||||
|
||||
|
||||
import net.sourceforge.filebot.ui.transferablepolicies.TransferablePolicy;
|
||||
|
||||
|
||||
public interface TransferablePolicySupport {
|
||||
|
||||
public TransferablePolicy getTransferablePolicy();
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
@ -96,7 +96,7 @@ public abstract class BackgroundFileTransferablePolicy<V> extends FileTransferab
|
|||
|
||||
|
||||
@Override
|
||||
protected Object doInBackground() {
|
||||
protected Void doInBackground() {
|
||||
load(files);
|
||||
|
||||
return null;
|
||||
|
|
|
@ -110,7 +110,7 @@ public abstract class FileTransferablePolicy implements TransferablePolicy {
|
|||
|
||||
|
||||
protected boolean accept(File file) {
|
||||
return false;
|
||||
return file.isFile() || file.isDirectory();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -12,16 +12,18 @@ import javax.swing.ImageIcon;
|
|||
|
||||
public abstract class EpisodeListClient {
|
||||
|
||||
private static final List<EpisodeListClient> registry = new ArrayList<EpisodeListClient>();
|
||||
|
||||
static {
|
||||
registry.add(new TvdotcomClient());
|
||||
registry.add(new AnidbClient());
|
||||
registry.add(new TVRageClient());
|
||||
}
|
||||
private static List<EpisodeListClient> registry;
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,33 +2,20 @@
|
|||
package net.sourceforge.filebot.web;
|
||||
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
|
||||
public class MovieDescriptor {
|
||||
|
||||
private final String title;
|
||||
private final Integer imdbId;
|
||||
|
||||
private final Integer year;
|
||||
private final URL imdbUrl;
|
||||
|
||||
|
||||
public MovieDescriptor(String description) {
|
||||
this(description, null);
|
||||
public MovieDescriptor(String title) {
|
||||
this(title, null);
|
||||
}
|
||||
|
||||
|
||||
public MovieDescriptor(String description, Integer imdbId) {
|
||||
this(description, imdbId, null, null);
|
||||
}
|
||||
|
||||
|
||||
public MovieDescriptor(String title, Integer imdbId, Integer year, URL imdbUrl) {
|
||||
public MovieDescriptor(String title, Integer imdbId) {
|
||||
this.title = title;
|
||||
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
|
||||
public String toString() {
|
||||
if (year == null)
|
||||
return title;
|
||||
|
||||
return String.format("%s (%d)", title, year);
|
||||
return title;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -35,9 +35,9 @@ public class OpenSubtitlesClient {
|
|||
* </tr>
|
||||
* </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;
|
||||
|
||||
|
@ -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 {
|
||||
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
|
||||
* (closing) clients program.
|
||||
*
|
||||
* @throws XmlRpcFault
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public synchronized void logout() {
|
||||
|
||||
// anonymous users will always get a 401 Unauthorized when trying to logout
|
||||
public synchronized void logout() throws XmlRpcFault {
|
||||
try {
|
||||
Map<String, String> response = (Map<String, String>) invoke("LogOut", token);
|
||||
checkStatus(response.get("status"));
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, "Exception while deactivating session", e);
|
||||
invoke("LogOut", token);
|
||||
|
||||
// anonymous users will always get a 401 Unauthorized when trying to logout
|
||||
// do not check status for logout response
|
||||
// checkStatus(response.get("status"));
|
||||
} finally {
|
||||
token = null;
|
||||
}
|
||||
|
||||
token = null;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
@ -32,7 +32,7 @@ public class OpenSubtitlesSubtitleClient extends SubtitleClient {
|
|||
|
||||
@Override
|
||||
public List<MovieDescriptor> search(String query) throws Exception {
|
||||
activate();
|
||||
login();
|
||||
|
||||
return client.searchMoviesOnIMDB(query);
|
||||
}
|
||||
|
@ -40,39 +40,45 @@ public class OpenSubtitlesSubtitleClient extends SubtitleClient {
|
|||
|
||||
@Override
|
||||
public List<OpenSubtitlesSubtitleDescriptor> getSubtitleList(MovieDescriptor descriptor) throws Exception {
|
||||
activate();
|
||||
login();
|
||||
|
||||
return client.searchSubtitles(descriptor.getImdbId());
|
||||
}
|
||||
|
||||
|
||||
private synchronized void activate() {
|
||||
try {
|
||||
if (!client.isLoggedOn()) {
|
||||
client.loginAnonymous();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
private synchronized void login() throws Exception {
|
||||
if (!client.isLoggedOn()) {
|
||||
client.loginAnonymous();
|
||||
}
|
||||
|
||||
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() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
logoutTimer.stop();
|
||||
|
||||
if (client.isLoggedOn()) {
|
||||
client.logout();
|
||||
}
|
||||
logout();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
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 LogoutTimerTask currentTimerTask = null;
|
||||
|
@ -85,7 +91,6 @@ public class OpenSubtitlesSubtitleClient extends SubtitleClient {
|
|||
|
||||
if (currentTimerTask != null) {
|
||||
currentTimerTask.cancel();
|
||||
daemon.purge();
|
||||
}
|
||||
|
||||
currentTimerTask = new LogoutTimerTask();
|
||||
|
@ -109,7 +114,7 @@ public class OpenSubtitlesSubtitleClient extends SubtitleClient {
|
|||
|
||||
@Override
|
||||
public void run() {
|
||||
doLogout.run();
|
||||
logout();
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.util.logging.Logger;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.sourceforge.filebot.FileFormat;
|
||||
import net.sourceforge.filebot.resources.ResourceManager;
|
||||
import net.sourceforge.tuned.XPathUtil;
|
||||
|
||||
|
@ -71,8 +72,7 @@ public class SubsceneSubtitleClient extends SubtitleClient {
|
|||
|
||||
Document dom = HtmlUtil.getHtmlDocument(url);
|
||||
|
||||
String downloadPath = XPathUtil.selectString("id('aspnetForm')/@action", dom);
|
||||
String viewstate = XPathUtil.selectString("id('__VIEWSTATE')/@value", dom);
|
||||
Pattern hrefPattern = Pattern.compile("javascript:Subtitle\\((\\d+), '(\\w+)', '0', '(\\d+)'\\);");
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
URL downloadUrl = new URL("http", host, downloadPath);
|
||||
Matcher matcher = hrefPattern.matcher(href);
|
||||
|
||||
Map<String, String> downloadParameters = parseParameters(href);
|
||||
downloadParameters.put("__VIEWSTATE", viewstate);
|
||||
if (!matcher.matches())
|
||||
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) {
|
||||
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) {
|
||||
Matcher matcher = Pattern.compile("javascript:Subtitle\\((\\d+), '(\\w+)', '0', '(\\d+)'\\);").matcher(href);
|
||||
private URL getDownloadUrl(URL referer, String subtitleId, String typeId) throws MalformedURLException {
|
||||
String basePath = FileFormat.getNameWithoutExtension(referer.getFile());
|
||||
String path = String.format("%s-dlpath-%s/%s.zipx", basePath, subtitleId, typeId);
|
||||
|
||||
if (!matcher.matches())
|
||||
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;
|
||||
return new URL(referer.getProtocol(), referer.getHost(), path);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ package net.sourceforge.filebot.web;
|
|||
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Map;
|
||||
|
||||
import net.sourceforge.tuned.DownloadTask;
|
||||
|
||||
|
@ -16,19 +15,23 @@ public class SubsceneSubtitleDescriptor implements SubtitleDescriptor {
|
|||
private final String author;
|
||||
private final boolean hearingImpaired;
|
||||
|
||||
private final Map<String, String> downloadParameters;
|
||||
private final String typeId;
|
||||
|
||||
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.language = language;
|
||||
this.numberOfCDs = numberOfCDs;
|
||||
this.author = author;
|
||||
this.hearingImpaired = hearingImpaired;
|
||||
|
||||
this.typeId = typeId;
|
||||
|
||||
this.downloadUrl = downloadUrl;
|
||||
this.downloadParameters = downloadParameters;
|
||||
this.referer = referer;
|
||||
}
|
||||
|
||||
|
||||
|
@ -60,13 +63,16 @@ public class SubsceneSubtitleDescriptor implements SubtitleDescriptor {
|
|||
|
||||
@Override
|
||||
public DownloadTask createDownloadTask() {
|
||||
return new DownloadTask(downloadUrl, downloadParameters);
|
||||
DownloadTask downloadTask = new DownloadTask(downloadUrl);
|
||||
downloadTask.setRequestHeader("Referer", referer.toString());
|
||||
|
||||
return downloadTask;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getArchiveType() {
|
||||
return downloadParameters.get("typeId");
|
||||
return typeId;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -11,15 +11,17 @@ import javax.swing.ImageIcon;
|
|||
|
||||
public abstract class SubtitleClient {
|
||||
|
||||
private static final List<SubtitleClient> registry = new ArrayList<SubtitleClient>();
|
||||
|
||||
static {
|
||||
registry.add(new OpenSubtitlesSubtitleClient());
|
||||
registry.add(new SubsceneSubtitleClient());
|
||||
}
|
||||
private static List<SubtitleClient> registry;
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@ import java.nio.ByteBuffer;
|
|||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
@ -20,7 +22,7 @@ import java.util.logging.Logger;
|
|||
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_PROGRESS = "download progress";
|
||||
|
@ -30,32 +32,44 @@ public class DownloadTask extends SwingWorker<ByteBuffer, Object> {
|
|||
PENDING,
|
||||
CONNECTING,
|
||||
DOWNLOADING,
|
||||
DONE;
|
||||
DONE
|
||||
}
|
||||
|
||||
private static final int BUFFER_SIZE = 4 * 1024;
|
||||
private final int BUFFER_SIZE = 4 * 1024;
|
||||
|
||||
private URL url;
|
||||
private ByteBuffer postdata = null;
|
||||
private ByteBuffer postdata;
|
||||
|
||||
private long size = -1;
|
||||
private long bytesRead = 0;
|
||||
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) {
|
||||
this.url = url;
|
||||
this(url, null);
|
||||
}
|
||||
|
||||
|
||||
public DownloadTask(URL url, ByteBuffer postdata) {
|
||||
public DownloadTask(URL url, Map<String, String> postParameters) {
|
||||
this.url = url;
|
||||
this.postdata = postdata;
|
||||
|
||||
if (postParameters != null) {
|
||||
this.postdata = encodeParameters(postParameters);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public DownloadTask(URL url, Map<String, String> postdata) {
|
||||
this(url, encodeParameters(postdata));
|
||||
protected HttpURLConnection createConnection() throws Exception {
|
||||
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 {
|
||||
setDownloadState(DownloadState.CONNECTING);
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
HttpURLConnection connection = createConnection();
|
||||
|
||||
if (postdata != null) {
|
||||
connection.setRequestMethod("POST");
|
||||
|
@ -75,31 +89,39 @@ public class DownloadTask extends SwingWorker<ByteBuffer, Object> {
|
|||
|
||||
size = connection.getContentLength();
|
||||
|
||||
for (String key : connection.getHeaderFields().keySet()) {
|
||||
responseHeaders.put(key, connection.getHeaderField(key));
|
||||
}
|
||||
|
||||
setDownloadState(DownloadState.DOWNLOADING);
|
||||
|
||||
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];
|
||||
int len = 0;
|
||||
|
||||
try {
|
||||
while (((len = in.read(buffer)) > 0) && !isCancelled()) {
|
||||
while (((len = in.read(buffer)) >= 0) && !isCancelled()) {
|
||||
out.write(buffer, 0, len);
|
||||
|
||||
bytesRead += len;
|
||||
getPropertyChangeSupport().firePropertyChange(DOWNLOAD_PROGRESS, null, bytesRead);
|
||||
|
||||
firePropertyChange(DOWNLOAD_PROGRESS, null, bytesRead);
|
||||
|
||||
if (isDownloadSizeKnown()) {
|
||||
setProgress((int) ((bytesRead * 100) / size));
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// IOException (Premature EOF) is always thrown when the size of
|
||||
// the response body is not known in advance, so we ignore it
|
||||
if (isSizeKnown())
|
||||
if (isDownloadSizeKnown())
|
||||
throw e;
|
||||
|
||||
} finally {
|
||||
in.close();
|
||||
out.close();
|
||||
connection.disconnect();
|
||||
}
|
||||
|
||||
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;
|
||||
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() {
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
|
||||
public boolean isSizeKnown() {
|
||||
public boolean isDownloadSizeKnown() {
|
||||
return size >= 0;
|
||||
}
|
||||
|
||||
|
||||
public long getSize() {
|
||||
public long getDownloadSize() {
|
||||
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();
|
||||
|
||||
int i = 0;
|
||||
|
|
|
@ -42,8 +42,6 @@ public class TemporaryFolder {
|
|||
for (TemporaryFolder folder : folders.values()) {
|
||||
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 {
|
||||
if (!root.exists()) {
|
||||
root.mkdir();
|
||||
|
@ -69,15 +74,37 @@ public class TemporaryFolder {
|
|||
}
|
||||
|
||||
|
||||
public void deleteFile(String name) {
|
||||
File file = new File(root, name);
|
||||
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
/**
|
||||
* Creates an empty file in this temporary folder, using the given prefix and suffix to
|
||||
* generate its name.
|
||||
*
|
||||
* @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() {
|
||||
return root;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,10 @@
|
|||
|
||||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
|
@ -26,14 +30,15 @@ public class ProgressIndicator extends JComponent {
|
|||
private int indeterminateShapeCount = 1;
|
||||
|
||||
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 remainingStroke = new BasicStroke(remainingStrokeWidth, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND);
|
||||
|
||||
private Color progressColor = Color.orange;
|
||||
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 paintBackground = false;
|
||||
|
@ -42,6 +47,8 @@ public class ProgressIndicator extends JComponent {
|
|||
private final Arc2D arc = new Arc2D.Double();
|
||||
private final Ellipse2D circle = new Ellipse2D.Double();
|
||||
|
||||
private final Dimension baseSize = new Dimension(32, 32);
|
||||
|
||||
|
||||
public ProgressIndicator() {
|
||||
this(null);
|
||||
|
@ -53,7 +60,7 @@ public class ProgressIndicator extends JComponent {
|
|||
|
||||
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
|
||||
public void paint(Graphics g) {
|
||||
public void paintComponent(Graphics 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);
|
||||
|
||||
if (paintBackground) {
|
||||
frame.setFrame(0, 0, getWidth(), getHeight());
|
||||
frame.setFrame(0, 0, baseSize.width, baseSize.height);
|
||||
|
||||
g2d.setPaint(getBackground());
|
||||
circle.setFrame(frame);
|
||||
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) {
|
||||
paintProgress(g2d);
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
package net.sourceforge.tuned.ui;
|
||||
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Point;
|
||||
import java.awt.Window;
|
||||
|
|
Loading…
Reference in New Issue