diff --git a/source/net/sourceforge/filebot/ui/MediaInfoPane.java b/source/net/sourceforge/filebot/ui/MediaInfoPane.java index 5e43870e..2461987d 100644 --- a/source/net/sourceforge/filebot/ui/MediaInfoPane.java +++ b/source/net/sourceforge/filebot/ui/MediaInfoPane.java @@ -49,6 +49,7 @@ public class MediaInfoPane extends JTabbedPane { public void addTableTab(String title, Map data) { JTable table = new JTable(new ParameterTableModel(data)); + table.setFillsViewportHeight(true); // allow sorting table.setAutoCreateRowSorter(true); @@ -69,6 +70,7 @@ public class MediaInfoPane extends JTabbedPane { @Override public void actionPerformed(ActionEvent e) { dialog.setVisible(false); + dialog.dispose(); } }; @@ -81,12 +83,12 @@ public class MediaInfoPane extends JTabbedPane { dialog.setVisible(true); } - + private static class ParameterTableModel extends AbstractTableModel { private final List> data; - + public ParameterTableModel(Map data) { this.data = new ArrayList>(data.entrySet()); } diff --git a/source/net/sourceforge/filebot/ui/panel/subtitle/SubtitleDownloadComponent.java b/source/net/sourceforge/filebot/ui/panel/subtitle/SubtitleDownloadComponent.java index e50c39a5..f69d2f89 100644 --- a/source/net/sourceforge/filebot/ui/panel/subtitle/SubtitleDownloadComponent.java +++ b/source/net/sourceforge/filebot/ui/panel/subtitle/SubtitleDownloadComponent.java @@ -3,6 +3,7 @@ package net.sourceforge.filebot.ui.panel.subtitle; import static net.sourceforge.filebot.FileBotUtilities.*; +import static net.sourceforge.filebot.ui.panel.subtitle.SubtitleUtilities.*; import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; @@ -11,15 +12,8 @@ import java.awt.event.MouseListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.channels.FileChannel; -import java.util.ArrayDeque; -import java.util.ArrayList; import java.util.Comparator; -import java.util.Deque; import java.util.List; import java.util.concurrent.CancellationException; import java.util.logging.Level; @@ -33,6 +27,7 @@ import javax.swing.JComponent; import javax.swing.JFileChooser; import javax.swing.JLabel; import javax.swing.JList; +import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JTextField; @@ -56,18 +51,14 @@ import ca.odell.glazedlists.swing.TextComponentMatcherEditor; import net.miginfocom.swing.MigLayout; import net.sourceforge.filebot.ResourceManager; -import net.sourceforge.filebot.subtitle.SubtitleElement; -import net.sourceforge.filebot.subtitle.SubtitleFormat; -import net.sourceforge.filebot.subtitle.SubtitleReader; import net.sourceforge.filebot.ui.panel.subtitle.SubtitlePackage.Download.Phase; import net.sourceforge.filebot.ui.transfer.DefaultTransferHandler; -import net.sourceforge.tuned.ByteBufferInputStream; import net.sourceforge.tuned.ExceptionUtilities; import net.sourceforge.tuned.ui.ListView; import net.sourceforge.tuned.ui.TunedUtilities; -public class SubtitleDownloadComponent extends JComponent { +class SubtitleDownloadComponent extends JComponent { private EventList packages = new BasicEventList(); @@ -129,7 +120,7 @@ public class SubtitleDownloadComponent extends JComponent { @Override public void actionPerformed(ActionEvent e) { - fetchAll(packageList.getSelectedValues()); + fetch(packageList.getSelectedValues()); } }); @@ -212,7 +203,7 @@ public class SubtitleDownloadComponent extends JComponent { } - private void fetchAll(Object[] selection) { + private void fetch(Object[] selection) { for (Object value : selection) { fetch((SubtitlePackage) value); } @@ -270,46 +261,12 @@ public class SubtitleDownloadComponent extends JComponent { private void open(MemoryFile file) throws IOException { - Deque priorityList = new ArrayDeque(); + SubtitleViewer viewer = new SubtitleViewer(file.getName()); + viewer.getTitleLabel().setText("Subtitle Viewer"); + viewer.getInfoLabel().setText(file.getPath()); - // gather all formats, put likely formats first - for (SubtitleFormat format : SubtitleFormat.values()) { - if (format.filter().accept(file.getName())) { - priorityList.addFirst(format); - } else { - priorityList.addLast(format); - } - } - - // decode subtitle file with the first reader that seems to work - for (SubtitleFormat format : priorityList) { - InputStream data = new ByteBufferInputStream(file.getData()); - SubtitleReader reader = format.newReader(new InputStreamReader(data, "UTF-8")); - - try { - if (reader.hasNext()) { - // correct format found - List list = new ArrayList(500); - - // read subtitle file - while (reader.hasNext()) { - list.add(reader.next()); - } - - SubtitleViewer viewer = new SubtitleViewer(file.getName()); - viewer.getTitleLabel().setText("Subtitle Viewer"); - viewer.getInfoLabel().setText(file.getPath()); - - viewer.setData(list); - viewer.setVisible(true); - - // we're done - return; - } - } finally { - reader.close(); - } - } + viewer.setData(decode(file)); + viewer.setVisible(true); } @@ -345,17 +302,6 @@ public class SubtitleDownloadComponent extends JComponent { } - private void write(MemoryFile source, File destination) throws IOException { - FileChannel fileChannel = new FileOutputStream(destination).getChannel(); - - try { - fileChannel.write(source.getData()); - } finally { - fileChannel.close(); - } - } - - private final Action clearFilterAction = new AbstractAction(null, ResourceManager.getIcon("edit.clear")) { @Override @@ -372,7 +318,7 @@ public class SubtitleDownloadComponent extends JComponent { if (SwingUtilities.isLeftMouseButton(e) && (e.getClickCount() == 2)) { JList list = (JList) e.getSource(); - fetchAll(list.getSelectedValues()); + fetch(list.getSelectedValues()); } } @@ -402,20 +348,22 @@ public class SubtitleDownloadComponent extends JComponent { final Object[] selection = list.getSelectedValues(); - Action downloadAction = new AbstractAction("Download", ResourceManager.getIcon("package.fetch")) { + if (selection.length > 0) { + JPopupMenu contextMenu = new JPopupMenu(); - @Override - public void actionPerformed(ActionEvent e) { - fetchAll(selection); - } - }; - - downloadAction.setEnabled(isPending(selection)); - - JPopupMenu contextMenu = new JPopupMenu(); - contextMenu.add(downloadAction); - - contextMenu.show(e.getComponent(), e.getX(), e.getY()); + JMenuItem item = contextMenu.add(new AbstractAction("Download", ResourceManager.getIcon("package.fetch")) { + + @Override + public void actionPerformed(ActionEvent e) { + fetch(selection); + } + }); + + // disable menu item if all selected elements have been fetched already + item.setEnabled(isPending(selection)); + + contextMenu.show(e.getComponent(), e.getX(), e.getY()); + } } } diff --git a/source/net/sourceforge/filebot/ui/panel/subtitle/SubtitlePackage.java b/source/net/sourceforge/filebot/ui/panel/subtitle/SubtitlePackage.java index c8c2a5a5..124429dd 100644 --- a/source/net/sourceforge/filebot/ui/panel/subtitle/SubtitlePackage.java +++ b/source/net/sourceforge/filebot/ui/panel/subtitle/SubtitlePackage.java @@ -24,7 +24,7 @@ import net.sourceforge.filebot.web.SubtitleDescriptor; import net.sourceforge.tuned.FileUtilities; -public class SubtitlePackage { +class SubtitlePackage { private final SubtitleDescriptor subtitle; diff --git a/source/net/sourceforge/filebot/ui/panel/subtitle/SubtitlePackageCellRenderer.java b/source/net/sourceforge/filebot/ui/panel/subtitle/SubtitlePackageCellRenderer.java index 241a23ff..954e6567 100644 --- a/source/net/sourceforge/filebot/ui/panel/subtitle/SubtitlePackageCellRenderer.java +++ b/source/net/sourceforge/filebot/ui/panel/subtitle/SubtitlePackageCellRenderer.java @@ -17,7 +17,7 @@ import net.sourceforge.filebot.ResourceManager; import net.sourceforge.tuned.ui.AbstractFancyListCellRenderer; -public class SubtitlePackageCellRenderer extends AbstractFancyListCellRenderer { +class SubtitlePackageCellRenderer extends AbstractFancyListCellRenderer { private final JLabel titleLabel = new JLabel(); private final JLabel languageLabel = new JLabel(); diff --git a/source/net/sourceforge/filebot/ui/panel/subtitle/SubtitleUtilities.java b/source/net/sourceforge/filebot/ui/panel/subtitle/SubtitleUtilities.java new file mode 100644 index 00000000..024f90d8 --- /dev/null +++ b/source/net/sourceforge/filebot/ui/panel/subtitle/SubtitleUtilities.java @@ -0,0 +1,81 @@ + +package net.sourceforge.filebot.ui.panel.subtitle; + + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.channels.FileChannel; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.List; + +import net.sourceforge.filebot.subtitle.SubtitleElement; +import net.sourceforge.filebot.subtitle.SubtitleFormat; +import net.sourceforge.filebot.subtitle.SubtitleReader; +import net.sourceforge.tuned.ByteBufferInputStream; + + +final class SubtitleUtilities { + + public static List decode(MemoryFile file) throws IOException { + Deque priorityList = new ArrayDeque(); + + // gather all formats, put likely formats first + for (SubtitleFormat format : SubtitleFormat.values()) { + if (format.filter().accept(file.getName())) { + priorityList.addFirst(format); + } else { + priorityList.addLast(format); + } + } + + // decode subtitle file with the first reader that seems to work + for (SubtitleFormat format : priorityList) { + InputStream data = new ByteBufferInputStream(file.getData()); + SubtitleReader reader = format.newReader(new InputStreamReader(data, "UTF-8")); + + try { + if (reader.hasNext()) { + // correct format found + List list = new ArrayList(500); + + // read subtitle file + while (reader.hasNext()) { + list.add(reader.next()); + } + + return list; + } + } finally { + reader.close(); + } + } + + // unsupported subtitle format + throw new IOException("Cannot read subtitle format"); + } + + + public static void write(MemoryFile source, File destination) throws IOException { + FileChannel fileChannel = new FileOutputStream(destination).getChannel(); + + try { + fileChannel.write(source.getData()); + } finally { + fileChannel.close(); + } + } + + + /** + * Dummy constructor to prevent instantiation. + */ + private SubtitleUtilities() { + throw new UnsupportedOperationException(); + } + +} diff --git a/source/net/sourceforge/filebot/web/OpenSubtitlesClient.java b/source/net/sourceforge/filebot/web/OpenSubtitlesClient.java index c83f6737..6d0ab388 100644 --- a/source/net/sourceforge/filebot/web/OpenSubtitlesClient.java +++ b/source/net/sourceforge/filebot/web/OpenSubtitlesClient.java @@ -130,6 +130,9 @@ public class OpenSubtitlesClient implements SubtitleProvider { // map id by name subLanguageCache.put(entry.getValue(), entry.getKey()); } + + // some additional special handling + subLanguageCache.put("Brazilian", "pob"); } } diff --git a/source/net/sourceforge/filebot/web/OpenSubtitlesXmlRpc.java b/source/net/sourceforge/filebot/web/OpenSubtitlesXmlRpc.java index 93eb1a1d..a8a5e804 100644 --- a/source/net/sourceforge/filebot/web/OpenSubtitlesXmlRpc.java +++ b/source/net/sourceforge/filebot/web/OpenSubtitlesXmlRpc.java @@ -5,8 +5,11 @@ package net.sourceforge.filebot.web; import static java.util.Collections.*; import static net.sourceforge.tuned.StringUtilities.*; +import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -19,6 +22,7 @@ import java.util.regex.Pattern; import redstone.xmlrpc.XmlRpcClient; import redstone.xmlrpc.XmlRpcException; import redstone.xmlrpc.XmlRpcFault; +import redstone.xmlrpc.util.Base64; import net.sourceforge.filebot.web.OpenSubtitlesSubtitleDescriptor.Property; @@ -169,6 +173,26 @@ public class OpenSubtitlesXmlRpc { } + @SuppressWarnings("unchecked") + public Collection detectLanguage(String text) throws XmlRpcFault { + try { + // base64 encoded text + String parameter = new String(Base64.encode(text.getBytes("utf-8"))); + + Map> response = (Map>) invoke("DetectLanguage", token, new Object[] { parameter }); + + if (response.containsKey("data")) { + return response.get("data").values(); + } + + return Collections.emptySet(); + } catch (UnsupportedEncodingException e) { + // will not happen + throw new RuntimeException(e); + } + } + + public Map getSubLanguages() throws XmlRpcFault { return getSubLanguages("en"); }