* Updated TVRageClient and AnidbClient
* BackgroundFileTransferablePolicy improved * lots of misc. changes
This commit is contained in:
parent
a01f5c41ee
commit
bc1e91ba10
|
@ -18,7 +18,7 @@ public class Main {
|
|||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
} catch (Exception e) {
|
||||
// should not happen
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
|
|
@ -20,7 +20,12 @@ public class FileBotUtil {
|
|||
component.getActionMap().put(key, action);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* invalid characters: \, /, :, *, ?, ", <, > and |
|
||||
*/
|
||||
public static final String INVALID_CHARACTERS = "\\/:*?\"<>|";
|
||||
|
||||
|
||||
/**
|
||||
* Strip string of invalid characters
|
||||
*
|
||||
|
@ -28,8 +33,8 @@ public class FileBotUtil {
|
|||
* @return filename stripped of invalid characters
|
||||
*/
|
||||
public static String validateFileName(String filename) {
|
||||
// strip \, /, :, *, ?, ", <, > and |
|
||||
return filename.replaceAll("[\\\\/:*?\"<>|]", "");
|
||||
// strip \, /, :, *, ?, ", <, > and |
|
||||
return filename.replaceAll(String.format("[%s]+", INVALID_CHARACTERS), "");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ public class FileFormat {
|
|||
else if (size >= KILO)
|
||||
return nf.format((double) size / KILO) + " KB";
|
||||
else
|
||||
return nf.format(size + " Byte");
|
||||
return nf.format(size) + " Byte";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ public class Settings {
|
|||
list.add(listNode.get(nodeKey, null));
|
||||
}
|
||||
} catch (BackingStoreException e) {
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
|
||||
return list;
|
||||
|
@ -107,7 +107,7 @@ public class Settings {
|
|||
map.put(mapNodeKey, mapNode.get(mapNodeKey, null));
|
||||
}
|
||||
} catch (BackingStoreException e) {
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
|
||||
return map;
|
||||
|
@ -132,7 +132,7 @@ public class Settings {
|
|||
try {
|
||||
map.put(entry.getKey(), new Integer(entry.getValue()));
|
||||
} catch (NumberFormatException e) {
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,7 +156,7 @@ public class Settings {
|
|||
prefs.removeNode();
|
||||
prefs = Preferences.userRoot().node(ROOT);
|
||||
} catch (BackingStoreException e) {
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -135,7 +135,7 @@ public class FileBotList extends JPanel implements Saveable, TransferablePolicyS
|
|||
out.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
// should not happen
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -193,7 +193,7 @@ public class FileBotTree extends JTree implements TransferablePolicySupport {
|
|||
Desktop.getDesktop().open(file);
|
||||
} catch (Exception e) {
|
||||
MessageManager.showWarning(e.getMessage());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,31 +56,16 @@ public class FileTree extends FileBotTree {
|
|||
}
|
||||
|
||||
|
||||
public void addFiles(DefaultMutableTreeNode parent, File files[]) {
|
||||
// folders first
|
||||
for (File f : files)
|
||||
if (f.isDirectory()) {
|
||||
// run through file tree
|
||||
DefaultMutableTreeNode node = new DefaultMutableTreeNode(f);
|
||||
addFiles(node, f.listFiles());
|
||||
parent.add(node);
|
||||
}
|
||||
|
||||
for (File f : files) {
|
||||
if (!f.isDirectory())
|
||||
parent.add(new DefaultMutableTreeNode(f));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
((BackgroundFileTransferablePolicy<?>) getTransferablePolicy()).cancelAll();
|
||||
|
||||
super.clear();
|
||||
contentChanged();
|
||||
}
|
||||
|
||||
|
||||
private class FileTreeTransferPolicy extends BackgroundFileTransferablePolicy<Object> implements PropertyChangeListener {
|
||||
private class FileTreeTransferPolicy extends BackgroundFileTransferablePolicy<DefaultMutableTreeNode> implements PropertyChangeListener {
|
||||
|
||||
public FileTreeTransferPolicy() {
|
||||
addPropertyChangeListener(LOADING_PROPERTY, this);
|
||||
|
@ -100,25 +85,50 @@ public class FileTree extends FileBotTree {
|
|||
|
||||
|
||||
@Override
|
||||
protected void load(List<File> files) {
|
||||
protected void process(List<DefaultMutableTreeNode> chunks) {
|
||||
DefaultMutableTreeNode root = (DefaultMutableTreeNode) getModel().getRoot();
|
||||
|
||||
File fileArray[] = new File[files.size()];
|
||||
files.toArray(fileArray);
|
||||
for (DefaultMutableTreeNode node : chunks) {
|
||||
root.add(node);
|
||||
}
|
||||
|
||||
addFiles(root, fileArray);
|
||||
updateUI();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void load(List<File> files) {
|
||||
for (File file : files) {
|
||||
publish(getTree(file));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private DefaultMutableTreeNode getTree(File file) {
|
||||
DefaultMutableTreeNode node = new DefaultMutableTreeNode(file);
|
||||
|
||||
if (file.isDirectory() && !Thread.currentThread().isInterrupted()) {
|
||||
// run through file tree
|
||||
for (File f : file.listFiles()) {
|
||||
node.add(getTree(f));
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
Boolean loading = (Boolean) evt.getNewValue();
|
||||
|
||||
if (loading) {
|
||||
FileTree.this.firePropertyChange(FileTree.LOADING_PROPERTY, null, true);
|
||||
} else {
|
||||
FileTree.this.firePropertyChange(FileTree.LOADING_PROPERTY, null, false);
|
||||
updateUI();
|
||||
contentChanged();
|
||||
if (evt.getPropertyName() == BackgroundFileTransferablePolicy.LOADING_PROPERTY) {
|
||||
Boolean loading = (Boolean) evt.getNewValue();
|
||||
|
||||
if (loading) {
|
||||
FileTree.this.firePropertyChange(FileTree.LOADING_PROPERTY, null, true);
|
||||
} else {
|
||||
FileTree.this.firePropertyChange(FileTree.LOADING_PROPERTY, null, false);
|
||||
|
||||
contentChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -120,8 +120,7 @@ public class SplitPanel extends ToolPanel implements ChangeListener {
|
|||
|
||||
private void setLastChildUserObject(DefaultMutableTreeNode root, int part, long size) {
|
||||
DefaultMutableTreeNode node = ((DefaultMutableTreeNode) root.getLastChild());
|
||||
String uo = "Part " + part + " (" + FileFormat.formatSize(size) + ")";
|
||||
node.setUserObject(uo);
|
||||
node.setUserObject(String.format("Part %d (%s)", part, FileFormat.formatSize(size)));
|
||||
}
|
||||
|
||||
|
||||
|
@ -183,7 +182,7 @@ public class SplitPanel extends ToolPanel implements ChangeListener {
|
|||
tree.setModel(model);
|
||||
} catch (Exception e) {
|
||||
// should not happen
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
|
||||
SplitPanel.this.firePropertyChange(LOADING_PROPERTY, null, false);
|
||||
|
|
|
@ -6,8 +6,9 @@ import java.awt.BorderLayout;
|
|||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.TreeMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
@ -76,7 +77,7 @@ public class TypePanel extends ToolPanel {
|
|||
|
||||
@Override
|
||||
protected DefaultTreeModel doInBackground() throws Exception {
|
||||
TreeMap<String, Collection<File>> map = new TreeMap<String, Collection<File>>();
|
||||
Map<String, Collection<File>> map = new HashMap<String, Collection<File>>();
|
||||
|
||||
for (File f : files) {
|
||||
String suffix = FileFormat.getSuffix(f);
|
||||
|
@ -131,7 +132,7 @@ public class TypePanel extends ToolPanel {
|
|||
tree.setModel(model);
|
||||
} catch (Exception e) {
|
||||
// should not happen
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
|
||||
TypePanel.this.firePropertyChange(LOADING_PROPERTY, null, false);
|
||||
|
|
|
@ -54,7 +54,7 @@ public class FileListTransferablePolicy extends FileTransferablePolicy {
|
|||
}
|
||||
} catch (IOException e) {
|
||||
// should not happen
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,8 +40,8 @@ public class ListPanel extends FileBotPanel {
|
|||
private LoadAction loadAction = new LoadAction(list);
|
||||
|
||||
private JTextField textField = new JTextField(String.format("Name - %s", INDEX_VARIABLE), 25);
|
||||
private SpinnerNumberModel fromSpinnerModel = new SpinnerNumberModel(1, 1, Integer.MAX_VALUE, 1);
|
||||
private SpinnerNumberModel toSpinnerModel = new SpinnerNumberModel(20, 1, Integer.MAX_VALUE, 1);
|
||||
private SpinnerNumberModel fromSpinnerModel = new SpinnerNumberModel(1, 0, Integer.MAX_VALUE, 1);
|
||||
private SpinnerNumberModel toSpinnerModel = new SpinnerNumberModel(20, 0, Integer.MAX_VALUE, 1);
|
||||
|
||||
|
||||
public ListPanel() {
|
||||
|
|
|
@ -71,7 +71,7 @@ public class NamesRenameListTransferablePolicy extends MultiTransferablePolicy {
|
|||
}
|
||||
} catch (Exception e) {
|
||||
// should not happen
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ public class HyperlinkLabel extends JLabel {
|
|||
Desktop.getDesktop().browse(url.toURI());
|
||||
} catch (Exception e) {
|
||||
// should not happen
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -387,7 +387,7 @@ public class SearchPanel extends FileBotPanel {
|
|||
tabbedPane.remove(episodeList);
|
||||
|
||||
MessageManager.showWarning(FileBotUtil.getRootCause(e).getMessage());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,16 +3,158 @@ package net.sourceforge.filebot.ui.panel.sfv;
|
|||
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
|
||||
import net.sourceforge.filebot.FileBotUtil;
|
||||
import net.sourceforge.filebot.FileFormat;
|
||||
import net.sourceforge.filebot.resources.ResourceManager;
|
||||
import net.sourceforge.filebot.ui.FileBotPanel;
|
||||
import net.sourceforge.filebot.ui.transfer.LoadAction;
|
||||
import net.sourceforge.filebot.ui.transfer.SaveAction;
|
||||
import net.sourceforge.tuned.ui.SelectDialog;
|
||||
|
||||
|
||||
public class SfvPanel extends FileBotPanel {
|
||||
|
||||
private SfvTable sfvTable = new SfvTable();
|
||||
|
||||
private TotalProgressPanel totalProgressPanel = new TotalProgressPanel();
|
||||
|
||||
|
||||
public SfvPanel() {
|
||||
super("SFV", ResourceManager.getIcon("panel.sfv"));
|
||||
add(new SfvTablePanel(), BorderLayout.CENTER);
|
||||
|
||||
setBorder(BorderFactory.createTitledBorder("SFV"));
|
||||
|
||||
JPanel southPanel = new JPanel(new BorderLayout());
|
||||
|
||||
JPanel southEastPanel = new JPanel(new BorderLayout());
|
||||
|
||||
Box buttonBox = Box.createHorizontalBox();
|
||||
buttonBox.setBorder(new EmptyBorder(5, 15, 5, 15));
|
||||
|
||||
buttonBox.add(new JButton(loadAction));
|
||||
buttonBox.add(Box.createHorizontalStrut(5));
|
||||
buttonBox.add(new JButton(saveAction));
|
||||
buttonBox.add(Box.createHorizontalStrut(5));
|
||||
buttonBox.add(new JButton(clearAction));
|
||||
southEastPanel.add(buttonBox, BorderLayout.SOUTH);
|
||||
|
||||
southPanel.add(southEastPanel, BorderLayout.WEST);
|
||||
southPanel.add(totalProgressPanel, BorderLayout.EAST);
|
||||
|
||||
add(new JScrollPane(sfvTable), BorderLayout.CENTER);
|
||||
add(southPanel, BorderLayout.SOUTH);
|
||||
|
||||
// Shortcut DELETE
|
||||
FileBotUtil.registerActionForKeystroke(this, KeyStroke.getKeyStroke("pressed DELETE"), removeAction);
|
||||
}
|
||||
|
||||
private final SaveAction saveAction = new SaveAction(sfvTable) {
|
||||
|
||||
private int index;
|
||||
|
||||
private String name;
|
||||
|
||||
|
||||
@Override
|
||||
protected void save(File file) {
|
||||
sfvTable.save(file, index);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String getDefaultFileName() {
|
||||
System.out.println(name);
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
SfvTableModel model = (SfvTableModel) sfvTable.getModel();
|
||||
|
||||
ArrayList<File> options = new ArrayList<File>();
|
||||
|
||||
for (int i = 0; i < model.getChecksumColumnCount(); i++) {
|
||||
options.add(model.getChecksumColumnRoot(i));
|
||||
}
|
||||
|
||||
File selected = null;
|
||||
|
||||
if (options.size() > 1) {
|
||||
SelectDialog<File> selectDialog = new SelectDialog<File>(SwingUtilities.getWindowAncestor(SfvPanel.this), options) {
|
||||
|
||||
@Override
|
||||
protected String convertValueToString(Object value) {
|
||||
File columnRoot = (File) value;
|
||||
return FileFormat.getName(columnRoot);
|
||||
}
|
||||
};
|
||||
|
||||
selectDialog.setText("Select checksum column:");
|
||||
selectDialog.setVisible(true);
|
||||
selected = selectDialog.getSelectedValue();
|
||||
} else if (options.size() == 1) {
|
||||
selected = options.get(0);
|
||||
}
|
||||
|
||||
if (selected == null)
|
||||
return;
|
||||
|
||||
index = options.indexOf(selected);
|
||||
name = FileFormat.getNameWithoutSuffix(selected);
|
||||
|
||||
if (name.isEmpty())
|
||||
name = "name";
|
||||
|
||||
name += ".sfv";
|
||||
|
||||
if (selected.isDirectory())
|
||||
name = new File(selected, name).getAbsolutePath();
|
||||
|
||||
super.actionPerformed(e);
|
||||
}
|
||||
};
|
||||
|
||||
private final LoadAction loadAction = new LoadAction(sfvTable);
|
||||
|
||||
private final AbstractAction clearAction = new AbstractAction("Clear", ResourceManager.getIcon("action.clear")) {
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
sfvTable.clear();
|
||||
}
|
||||
};
|
||||
|
||||
private final AbstractAction removeAction = new AbstractAction("Remove") {
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (sfvTable.getSelectedRowCount() < 1)
|
||||
return;
|
||||
|
||||
int row = sfvTable.getSelectionModel().getMinSelectionIndex();
|
||||
|
||||
sfvTable.removeRows(sfvTable.getSelectedRows());
|
||||
|
||||
int maxRow = sfvTable.getRowCount() - 1;
|
||||
|
||||
if (row > maxRow)
|
||||
row = maxRow;
|
||||
|
||||
sfvTable.getSelectionModel().setSelectionInterval(row, row);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ 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.transferablepolicies.BackgroundFileTransferablePolicy;
|
||||
import net.sourceforge.filebot.ui.transferablepolicies.NullTransferablePolicy;
|
||||
import net.sourceforge.filebot.ui.transferablepolicies.TransferablePolicy;
|
||||
import net.sourceforge.filebot.ui.transferablepolicies.TransferablePolicySupport;
|
||||
|
@ -91,6 +92,8 @@ public class SfvTable extends JTable implements TransferablePolicySupport, Savea
|
|||
|
||||
|
||||
public void clear() {
|
||||
((BackgroundFileTransferablePolicy<?>) getTransferablePolicy()).cancelAll();
|
||||
|
||||
((SfvTableModel) getModel()).clear();
|
||||
}
|
||||
|
||||
|
@ -165,7 +168,7 @@ public class SfvTable extends JTable implements TransferablePolicySupport, Savea
|
|||
out.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
// should not happen
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -179,7 +179,7 @@ public class SfvTableModel extends AbstractTableModel {
|
|||
for (ChecksumRow row : rows) {
|
||||
Checksum checksum = row.getChecksum(columnRoot);
|
||||
|
||||
if (checksum != null && checksum.getState() == Checksum.State.READY) {
|
||||
if ((checksum != null) && (checksum.getState() == Checksum.State.READY)) {
|
||||
checksumMap.put(row.getName(), checksum);
|
||||
}
|
||||
}
|
||||
|
@ -236,6 +236,12 @@ public class SfvTableModel extends AbstractTableModel {
|
|||
public File getColumnRoot() {
|
||||
return columnRoot;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getName();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,158 +0,0 @@
|
|||
|
||||
package net.sourceforge.filebot.ui.panel.sfv;
|
||||
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
|
||||
import net.sourceforge.filebot.FileBotUtil;
|
||||
import net.sourceforge.filebot.FileFormat;
|
||||
import net.sourceforge.filebot.resources.ResourceManager;
|
||||
import net.sourceforge.filebot.ui.transfer.LoadAction;
|
||||
import net.sourceforge.filebot.ui.transfer.SaveAction;
|
||||
import net.sourceforge.tuned.ui.SelectDialog;
|
||||
|
||||
|
||||
public class SfvTablePanel extends JPanel {
|
||||
|
||||
private SfvTable sfvTable = new SfvTable();
|
||||
|
||||
private TotalProgressPanel totalProgressPanel = new TotalProgressPanel();
|
||||
|
||||
|
||||
public SfvTablePanel() {
|
||||
super(new BorderLayout());
|
||||
|
||||
setBorder(BorderFactory.createTitledBorder("SFV"));
|
||||
|
||||
JPanel southPanel = new JPanel(new BorderLayout());
|
||||
|
||||
JPanel southEastPanel = new JPanel(new BorderLayout());
|
||||
|
||||
Box buttonBox = Box.createHorizontalBox();
|
||||
buttonBox.setBorder(new EmptyBorder(5, 15, 5, 15));
|
||||
|
||||
buttonBox.add(new JButton(loadAction));
|
||||
buttonBox.add(Box.createHorizontalStrut(5));
|
||||
buttonBox.add(new JButton(saveAction));
|
||||
buttonBox.add(Box.createHorizontalStrut(5));
|
||||
buttonBox.add(new JButton(clearAction));
|
||||
southEastPanel.add(buttonBox, BorderLayout.SOUTH);
|
||||
|
||||
southPanel.add(southEastPanel, BorderLayout.WEST);
|
||||
southPanel.add(totalProgressPanel, BorderLayout.EAST);
|
||||
|
||||
add(new JScrollPane(sfvTable), BorderLayout.CENTER);
|
||||
add(southPanel, BorderLayout.SOUTH);
|
||||
|
||||
// Shortcut DELETE
|
||||
FileBotUtil.registerActionForKeystroke(this, KeyStroke.getKeyStroke("pressed DELETE"), removeAction);
|
||||
}
|
||||
|
||||
private final SaveAction saveAction = new SaveAction(sfvTable) {
|
||||
|
||||
private int index;
|
||||
|
||||
private String name;
|
||||
|
||||
|
||||
@Override
|
||||
protected void save(File file) {
|
||||
sfvTable.save(file, index);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected String getDefaultFileName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
SfvTableModel model = (SfvTableModel) sfvTable.getModel();
|
||||
|
||||
ArrayList<File> options = new ArrayList<File>();
|
||||
|
||||
for (int i = 0; i < model.getChecksumColumnCount(); i++) {
|
||||
options.add(model.getChecksumColumnRoot(i));
|
||||
}
|
||||
|
||||
File selected = null;
|
||||
|
||||
if (options.size() > 1) {
|
||||
SelectDialog<File> selectDialog = new SelectDialog<File>(SwingUtilities.getWindowAncestor(SfvTablePanel.this), options) {
|
||||
|
||||
@Override
|
||||
protected String convertValueToString(Object value) {
|
||||
File columnRoot = (File) value;
|
||||
return FileFormat.getName(columnRoot);
|
||||
}
|
||||
};
|
||||
|
||||
selectDialog.setText("Select checksum column:");
|
||||
selectDialog.setVisible(true);
|
||||
selected = selectDialog.getSelectedValue();
|
||||
} else if (options.size() == 1) {
|
||||
selected = options.get(0);
|
||||
}
|
||||
|
||||
if (selected == null)
|
||||
return;
|
||||
|
||||
index = options.indexOf(selected);
|
||||
name = FileFormat.getNameWithoutSuffix(selected);
|
||||
|
||||
if (name.isEmpty())
|
||||
name = "name";
|
||||
|
||||
name += ".sfv";
|
||||
|
||||
if (selected.isDirectory())
|
||||
name = new File(selected, name).getAbsolutePath();
|
||||
|
||||
super.actionPerformed(e);
|
||||
}
|
||||
};
|
||||
|
||||
private final LoadAction loadAction = new LoadAction(sfvTable);
|
||||
|
||||
private final AbstractAction clearAction = new AbstractAction("Clear", ResourceManager.getIcon("action.clear")) {
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
sfvTable.clear();
|
||||
}
|
||||
};
|
||||
|
||||
private final AbstractAction removeAction = new AbstractAction("Remove") {
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (sfvTable.getSelectedRowCount() < 1)
|
||||
return;
|
||||
|
||||
int row = sfvTable.getSelectionModel().getMinSelectionIndex();
|
||||
|
||||
sfvTable.removeRows(sfvTable.getSelectedRows());
|
||||
|
||||
int maxRow = sfvTable.getRowCount() - 1;
|
||||
|
||||
if (row > maxRow)
|
||||
row = maxRow;
|
||||
|
||||
sfvTable.getSelectionModel().setSelectionInterval(row, row);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -15,166 +15,132 @@ import java.util.regex.Pattern;
|
|||
|
||||
import net.sourceforge.filebot.FileFormat;
|
||||
import net.sourceforge.filebot.ui.transferablepolicies.BackgroundFileTransferablePolicy;
|
||||
import net.sourceforge.filebot.ui.transferablepolicies.MultiTransferablePolicy;
|
||||
|
||||
|
||||
public class SfvTransferablePolicy extends MultiTransferablePolicy {
|
||||
public class SfvTransferablePolicy extends BackgroundFileTransferablePolicy<SfvTableModel.Entry> {
|
||||
|
||||
private SfvTableModel tableModel;
|
||||
|
||||
|
||||
public SfvTransferablePolicy(SfvTableModel tableModel) {
|
||||
this.tableModel = tableModel;
|
||||
|
||||
addPolicy(new SfvFilePolicy());
|
||||
addPolicy(new DefaultFilePolicy());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean accept(File file) {
|
||||
return file.isFile() || file.isDirectory();
|
||||
}
|
||||
|
||||
private class SfvFilePolicy extends BackgroundFileTransferablePolicy<SfvTableModel.Entry> {
|
||||
|
||||
@Override
|
||||
protected boolean accept(File file) {
|
||||
// accept sfv files
|
||||
return file.isFile() && FileFormat.getSuffix(file).equalsIgnoreCase("sfv");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void clear() {
|
||||
tableModel.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void clear() {
|
||||
cancelAll();
|
||||
tableModel.clear();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void process(List<SfvTableModel.Entry> chunks) {
|
||||
tableModel.addAll(chunks);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void process(List<SfvTableModel.Entry> chunks) {
|
||||
tableModel.addAll(chunks);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void load(List<File> files) {
|
||||
synchronized (ChecksumComputationExecutor.getInstance()) {
|
||||
ChecksumComputationExecutor.getInstance().pause();
|
||||
protected void loadSfvFile(File sfvFile) {
|
||||
try {
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(sfvFile)));
|
||||
|
||||
String line = null;
|
||||
Pattern pattern = Pattern.compile("(.*)\\s+(\\p{XDigit}{8})");
|
||||
|
||||
while (((line = in.readLine()) != null) && !Thread.currentThread().isInterrupted()) {
|
||||
if (line.startsWith(";"))
|
||||
continue;
|
||||
|
||||
Matcher matcher = pattern.matcher(line);
|
||||
|
||||
if (!matcher.matches())
|
||||
continue;
|
||||
|
||||
String filename = matcher.group(1);
|
||||
String checksumString = matcher.group(2);
|
||||
|
||||
publish(new SfvTableModel.Entry(filename, new Checksum(checksumString), sfvFile));
|
||||
|
||||
File compareColumnRoot = sfvFile.getParentFile();
|
||||
File compareFile = new File(compareColumnRoot, filename);
|
||||
|
||||
if (compareFile.exists()) {
|
||||
publish(new SfvTableModel.Entry(filename, new Checksum(compareFile), compareColumnRoot));
|
||||
}
|
||||
}
|
||||
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
// should not happen
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "files, folders and sfv files";
|
||||
}
|
||||
|
||||
|
||||
private boolean isSfvFileList(List<File> files) {
|
||||
for (File file : files) {
|
||||
if (!FileFormat.getSuffix(file).equalsIgnoreCase("sfv"))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void load(List<File> files) {
|
||||
synchronized (ChecksumComputationExecutor.getInstance()) {
|
||||
ChecksumComputationExecutor.getInstance().pause();
|
||||
|
||||
if (isSfvFileList(files)) {
|
||||
// one or more sfv files
|
||||
for (File file : files) {
|
||||
load(file);
|
||||
loadSfvFile(file);
|
||||
}
|
||||
} else if ((files.size() == 1) && files.get(0).isDirectory()) {
|
||||
// one single folder
|
||||
File file = files.get(0);
|
||||
|
||||
ChecksumComputationExecutor.getInstance().resume();
|
||||
for (File f : file.listFiles()) {
|
||||
load(f, file, "");
|
||||
}
|
||||
} else {
|
||||
// bunch of files
|
||||
for (File f : files) {
|
||||
load(f, f.getParentFile(), "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void load(File sfvFile) {
|
||||
|
||||
try {
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(sfvFile)));
|
||||
|
||||
String line = null;
|
||||
Pattern pattern = Pattern.compile("(.*)\\s+(\\p{XDigit}{8})");
|
||||
|
||||
while ((line = in.readLine()) != null) {
|
||||
if (line.startsWith(";"))
|
||||
continue;
|
||||
|
||||
Matcher matcher = pattern.matcher(line);
|
||||
|
||||
if (!matcher.matches())
|
||||
continue;
|
||||
|
||||
String filename = matcher.group(1);
|
||||
String checksumString = matcher.group(2);
|
||||
|
||||
publish(new SfvTableModel.Entry(filename, new Checksum(checksumString), sfvFile));
|
||||
|
||||
File compareColumnRoot = sfvFile.getParentFile();
|
||||
File compareFile = new File(compareColumnRoot, filename);
|
||||
|
||||
if (compareFile.exists()) {
|
||||
publish(new SfvTableModel.Entry(filename, new Checksum(compareFile), compareColumnRoot));
|
||||
}
|
||||
}
|
||||
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
// should not happen
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
|
||||
}
|
||||
ChecksumComputationExecutor.getInstance().resume();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "sfv files";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private class DefaultFilePolicy extends BackgroundFileTransferablePolicy<SfvTableModel.Entry> {
|
||||
protected void load(File file, File columnRoot, String prefix) {
|
||||
if (Thread.currentThread().isInterrupted())
|
||||
return;
|
||||
|
||||
@Override
|
||||
protected boolean accept(File file) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void clear() {
|
||||
tableModel.clear();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void process(List<SfvTableModel.Entry> chunks) {
|
||||
tableModel.addAll(chunks);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void load(List<File> files) {
|
||||
if (files.isEmpty())
|
||||
return;
|
||||
|
||||
synchronized (ChecksumComputationExecutor.getInstance()) {
|
||||
ChecksumComputationExecutor.getInstance().pause();
|
||||
|
||||
File firstFile = files.get(0);
|
||||
|
||||
if ((files.size() == 1) && firstFile.isDirectory()) {
|
||||
for (File f : firstFile.listFiles()) {
|
||||
load(f, firstFile, "");
|
||||
}
|
||||
} else {
|
||||
for (File f : files) {
|
||||
load(f, f.getParentFile(), "");
|
||||
}
|
||||
}
|
||||
|
||||
ChecksumComputationExecutor.getInstance().resume();
|
||||
if (file.isDirectory()) {
|
||||
// load all files in the file tree
|
||||
String newPrefix = prefix + file.getName() + "/";
|
||||
for (File f : file.listFiles()) {
|
||||
load(f, columnRoot, newPrefix);
|
||||
}
|
||||
} else if (file.isFile()) {
|
||||
publish(new SfvTableModel.Entry(prefix + file.getName(), new Checksum(file), columnRoot));
|
||||
}
|
||||
|
||||
|
||||
protected void load(File file, File columnRoot, String prefix) {
|
||||
if (file.isDirectory()) {
|
||||
// load all files in the file tree
|
||||
String newPrefix = prefix + file.getName() + "/";
|
||||
for (File f : file.listFiles()) {
|
||||
load(f, columnRoot, newPrefix);
|
||||
}
|
||||
} else if (file.isFile()) {
|
||||
publish(new SfvTableModel.Entry(prefix + file.getName(), new Checksum(file), columnRoot));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "files and folders";
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ public class FileTransferable implements Transferable {
|
|||
return new DataFlavor("text/uri-list;class=java.lang.String");
|
||||
} catch (ClassNotFoundException e) {
|
||||
// will never happen
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -8,7 +8,6 @@ import java.io.File;
|
|||
import javax.swing.AbstractAction;
|
||||
import javax.swing.JFileChooser;
|
||||
|
||||
import net.sourceforge.filebot.FileBotUtil;
|
||||
import net.sourceforge.filebot.resources.ResourceManager;
|
||||
|
||||
|
||||
|
@ -45,7 +44,7 @@ public class SaveAction extends AbstractAction {
|
|||
JFileChooser chooser = new JFileChooser();
|
||||
|
||||
chooser.setMultiSelectionEnabled(false);
|
||||
chooser.setSelectedFile(new File(FileBotUtil.validateFileName(getDefaultFileName())));
|
||||
chooser.setSelectedFile(new File(getDefaultFileName()));
|
||||
|
||||
if (chooser.showSaveDialog(null) != JFileChooser.APPROVE_OPTION)
|
||||
return;
|
||||
|
|
|
@ -40,7 +40,7 @@ public class SaveableExportHandler implements ExportHandler {
|
|||
}
|
||||
} catch (Exception e) {
|
||||
// should not happen
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ public class SaveableExportHandler implements ExportHandler {
|
|||
return new FileTransferable(temporaryFile);
|
||||
} catch (IOException e) {
|
||||
// should not happen
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -4,6 +4,8 @@ package net.sourceforge.filebot.ui.transfer;
|
|||
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.dnd.InvalidDnDOperationException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.swing.TransferHandler;
|
||||
import javax.swing.TransferHandler.TransferSupport;
|
||||
|
@ -49,7 +51,11 @@ public class TransferablePolicyImportHandler implements ImportHandler {
|
|||
|
||||
Transferable t = support.getTransferable();
|
||||
|
||||
transferablePolicySupport.getTransferablePolicy().handleTransferable(t, add);
|
||||
try {
|
||||
transferablePolicySupport.getTransferablePolicy().handleTransferable(t, add);
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -3,20 +3,22 @@ package net.sourceforge.filebot.ui.transferablepolicies;
|
|||
|
||||
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import javax.swing.SwingWorker;
|
||||
|
||||
import net.sourceforge.tuned.ui.SwingWorkerPropertyChangeAdapter;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
|
||||
public abstract class BackgroundFileTransferablePolicy<V> extends FileTransferablePolicy {
|
||||
|
||||
public static final String LOADING_PROPERTY = "loading";
|
||||
|
||||
private BackgroundWorker backgroundWorker;
|
||||
private SingleThreadExecutor executor = null;
|
||||
|
||||
|
||||
@Override
|
||||
|
@ -29,9 +31,34 @@ public abstract class BackgroundFileTransferablePolicy<V> extends FileTransferab
|
|||
if (!add)
|
||||
clear();
|
||||
|
||||
backgroundWorker = new BackgroundWorker(files);
|
||||
backgroundWorker.addPropertyChangeListener(new BackgroundWorkerListener());
|
||||
backgroundWorker.execute();
|
||||
submit(new LoadFilesTask(files));
|
||||
}
|
||||
|
||||
|
||||
protected void submit(Runnable task) {
|
||||
synchronized (this) {
|
||||
if (executor == null) {
|
||||
executor = new SingleThreadExecutor();
|
||||
}
|
||||
}
|
||||
|
||||
executor.submit(task);
|
||||
}
|
||||
|
||||
|
||||
public boolean isActive() {
|
||||
return executor.isActive();
|
||||
}
|
||||
|
||||
|
||||
public void cancelAll() {
|
||||
synchronized (this) {
|
||||
if (executor != null) {
|
||||
// interrupt all threads
|
||||
executor.shutdownNow();
|
||||
executor = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -41,7 +68,7 @@ public abstract class BackgroundFileTransferablePolicy<V> extends FileTransferab
|
|||
* @param chunks
|
||||
*/
|
||||
protected final void publish(V... chunks) {
|
||||
backgroundWorker.publishChunks(chunks);
|
||||
SwingUtilities.invokeLater(new ProcessChunksTask(chunks, Thread.currentThread()));
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,59 +78,95 @@ public abstract class BackgroundFileTransferablePolicy<V> extends FileTransferab
|
|||
*
|
||||
* @param chunks
|
||||
*/
|
||||
protected void process(List<V> chunks) {
|
||||
|
||||
}
|
||||
protected abstract void process(List<V> chunks);
|
||||
|
||||
|
||||
private class BackgroundWorker extends SwingWorker<Object, V> {
|
||||
private class LoadFilesTask implements Runnable {
|
||||
|
||||
private List<File> files;
|
||||
|
||||
|
||||
public BackgroundWorker(List<File> files) {
|
||||
public LoadFilesTask(List<File> files) {
|
||||
this.files = files;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void process(List<V> chunks) {
|
||||
BackgroundFileTransferablePolicy.this.process(chunks);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* make publish() accessible
|
||||
*
|
||||
* @param chunks
|
||||
*/
|
||||
public void publishChunks(V... chunks) {
|
||||
super.publish(chunks);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Object doInBackground() throws Exception {
|
||||
public void run() {
|
||||
load(files);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class BackgroundWorkerListener extends SwingWorkerPropertyChangeAdapter {
|
||||
private class ProcessChunksTask implements Runnable {
|
||||
|
||||
@Override
|
||||
public void started(PropertyChangeEvent evt) {
|
||||
setEnabled(false);
|
||||
firePropertyChange(LOADING_PROPERTY, null, true);
|
||||
private V[] chunks;
|
||||
private Thread publisher;
|
||||
|
||||
|
||||
public ProcessChunksTask(V[] chunks, Thread publisher) {
|
||||
this.chunks = chunks;
|
||||
this.publisher = publisher;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void done(PropertyChangeEvent evt) {
|
||||
firePropertyChange(LOADING_PROPERTY, null, false);
|
||||
setEnabled(true);
|
||||
public void run() {
|
||||
if (!publisher.isInterrupted() && publisher.isAlive()) {
|
||||
process(Arrays.asList(chunks));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class SingleThreadExecutor extends ThreadPoolExecutor {
|
||||
|
||||
private final AtomicInteger count = new AtomicInteger(0);
|
||||
|
||||
|
||||
public SingleThreadExecutor() {
|
||||
super(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
|
||||
}
|
||||
|
||||
|
||||
public boolean isActive() {
|
||||
return count.get() > 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void execute(Runnable command) {
|
||||
|
||||
if (count.getAndIncrement() <= 0) {
|
||||
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
firePropertyChange(LOADING_PROPERTY, false, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
super.execute(command);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void afterExecute(Runnable r, Throwable t) {
|
||||
super.afterExecute(r, t);
|
||||
|
||||
if (count.decrementAndGet() <= 0) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
firePropertyChange(LOADING_PROPERTY, true, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -65,10 +65,10 @@ public abstract class FileTransferablePolicy extends TransferablePolicy {
|
|||
}
|
||||
} catch (UnsupportedFlavorException e) {
|
||||
// should not happen
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
} catch (IOException e) {
|
||||
// should not happen
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -31,7 +31,7 @@ public abstract class TextTransferablePolicy extends TransferablePolicy {
|
|||
load(string);
|
||||
} catch (Exception e) {
|
||||
// should not happen
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,10 @@ public abstract class TransferablePolicy {
|
|||
public static final String ENABLED_PROPERTY = "enabled";
|
||||
|
||||
|
||||
public abstract String getDescription();
|
||||
|
||||
|
||||
//TODO remove enabled stuff
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
@ -59,11 +63,8 @@ public abstract class TransferablePolicy {
|
|||
}
|
||||
|
||||
|
||||
public void firePropertyChange(PropertyChangeEvent evt) {
|
||||
protected void firePropertyChange(PropertyChangeEvent evt) {
|
||||
propertyChangeSupport.firePropertyChange(evt);
|
||||
}
|
||||
|
||||
|
||||
public abstract String getDescription();
|
||||
|
||||
}
|
||||
|
|
|
@ -10,9 +10,9 @@ import java.text.NumberFormat;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
@ -26,7 +26,7 @@ import org.xml.sax.SAXException;
|
|||
|
||||
public class AnidbClient extends EpisodeListClient {
|
||||
|
||||
private Map<String, URL> cache = Collections.synchronizedMap(new TreeMap<String, URL>());
|
||||
private Map<String, URL> cache = Collections.synchronizedMap(new HashMap<String, URL>());
|
||||
|
||||
private String host = "anidb.info";
|
||||
|
||||
|
@ -48,13 +48,13 @@ public class AnidbClient extends EpisodeListClient {
|
|||
|
||||
if (!nodes.isEmpty())
|
||||
for (Node node : nodes) {
|
||||
String type = XPathUtil.selectString("./TD[3]/text()", node);
|
||||
String type = XPathUtil.selectString("./TD[3]", node);
|
||||
|
||||
// we only want shows
|
||||
if (type.equalsIgnoreCase("tv series")) {
|
||||
Node titleNode = XPathUtil.selectNode("./TD[2]/A", node);
|
||||
|
||||
String title = XPathUtil.selectString("text()", titleNode);
|
||||
String title = XPathUtil.selectString(".", titleNode);
|
||||
String href = XPathUtil.selectString("@href", titleNode);
|
||||
|
||||
String file = "/perl-bin/" + href;
|
||||
|
@ -75,7 +75,7 @@ public class AnidbClient extends EpisodeListClient {
|
|||
|
||||
if (!results.isEmpty()) {
|
||||
// get show's name from the document
|
||||
String header = XPathUtil.selectString("//DIV[@id='layout-content']//H1[1]/text()", dom);
|
||||
String header = XPathUtil.selectString("//DIV[@id='layout-content']//H1[1]", dom);
|
||||
String title = header.replaceFirst("Anime:\\s*", "");
|
||||
|
||||
cache.put(title, getSearchUrl(searchterm));
|
||||
|
@ -102,7 +102,7 @@ public class AnidbClient extends EpisodeListClient {
|
|||
f.setGroupingUsed(false);
|
||||
|
||||
for (Node node : nodes) {
|
||||
String number = XPathUtil.selectString("./TD[1]/A/text()", node);
|
||||
String number = XPathUtil.selectString("./TD[1]/A", node);
|
||||
String title = XPathUtil.selectString("./TD[2]/LABEL/text()", node);
|
||||
|
||||
if (title.startsWith("recap"))
|
||||
|
|
|
@ -147,7 +147,7 @@ public class DownloadTask extends SwingWorker<ByteBuffer, Object> {
|
|||
sb.append(URLEncoder.encode(parameters.get(key), "UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
// will never happen
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
|
||||
i++;
|
||||
|
|
|
@ -9,6 +9,8 @@ import java.io.Reader;
|
|||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
@ -29,7 +31,12 @@ public class HtmlUtil {
|
|||
|
||||
if (matcher.matches()) {
|
||||
String charsetName = matcher.group(1);
|
||||
return Charset.forName(charsetName);
|
||||
|
||||
try {
|
||||
return Charset.forName(charsetName);
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.WARNING, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,7 +52,7 @@ public class HtmlUtil {
|
|||
String encoding = connection.getContentEncoding();
|
||||
InputStream inputStream = connection.getInputStream();
|
||||
|
||||
if (encoding != null && encoding.equalsIgnoreCase("gzip"))
|
||||
if ((encoding != null) && encoding.equalsIgnoreCase("gzip"))
|
||||
inputStream = new GZIPInputStream(inputStream);
|
||||
|
||||
return getHtmlDocument(new InputStreamReader(inputStream, charset));
|
||||
|
|
|
@ -49,7 +49,7 @@ public class ImdbSearchEngine {
|
|||
}
|
||||
|
||||
|
||||
private MovieDescriptor parseMovieNode(Node node) throws MalformedURLException {
|
||||
private MovieDescriptor parseMovieNode(Node node) throws Exception {
|
||||
// ignore javascript links
|
||||
Node linkNode = XPathUtil.selectFirstNode("./A[count(@onclick) <= 0]", node);
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ import java.util.Collections;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
|
@ -27,7 +26,7 @@ import org.xml.sax.SAXException;
|
|||
|
||||
public class SubsceneClient {
|
||||
|
||||
private Map<String, URL> cache = Collections.synchronizedMap(new TreeMap<String, URL>());
|
||||
private Map<String, URL> cache = Collections.synchronizedMap(new HashMap<String, URL>());
|
||||
|
||||
private String host = "subscene.com";
|
||||
|
||||
|
|
|
@ -10,9 +10,9 @@ import java.net.URLEncoder;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
|
@ -28,7 +28,7 @@ import org.xml.sax.SAXException;
|
|||
|
||||
public class TVRageClient extends EpisodeListClient {
|
||||
|
||||
private Map<String, URL> cache = Collections.synchronizedMap(new TreeMap<String, URL>());
|
||||
private Map<String, URL> cache = Collections.synchronizedMap(new HashMap<String, URL>());
|
||||
|
||||
private String host = "www.tvrage.com";
|
||||
|
||||
|
@ -52,7 +52,7 @@ public class TVRageClient extends EpisodeListClient {
|
|||
|
||||
for (Node node : nodes) {
|
||||
String href = XPathUtil.selectString("@href", node);
|
||||
String title = XPathUtil.selectString("text()", node);
|
||||
String title = XPathUtil.selectString(".", node);
|
||||
|
||||
try {
|
||||
URL url = new URL(href);
|
||||
|
@ -77,13 +77,13 @@ public class TVRageClient extends EpisodeListClient {
|
|||
ArrayList<Episode> episodes = new ArrayList<Episode>();
|
||||
|
||||
for (Node node : nodes) {
|
||||
String seasonAndEpisodeNumber = XPathUtil.selectString("./TD[2]/A/text()", node);
|
||||
String title = XPathUtil.selectString("./TD[4]/A/text()", node);
|
||||
String seasonAndEpisodeNumber = XPathUtil.selectString("./TD[2]/A", node);
|
||||
String title = XPathUtil.selectString("./TD[5]/A", node);
|
||||
|
||||
List<Node> precedings = XPathUtil.selectNodes("../preceding-sibling::TABLE", node);
|
||||
Node previousTable = precedings.get(precedings.size() - 1);
|
||||
|
||||
String seasonHeader = XPathUtil.selectString("./TR/TD/FONT/text()", previousTable);
|
||||
String seasonHeader = XPathUtil.selectString("./TR/TD/FONT", previousTable);
|
||||
|
||||
Matcher seasonMatcher = Pattern.compile("Season (\\d+)").matcher(seasonHeader);
|
||||
|
||||
|
|
|
@ -11,9 +11,9 @@ import java.text.NumberFormat;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
@ -27,7 +27,7 @@ import org.xml.sax.SAXException;
|
|||
|
||||
public class TvdotcomClient extends EpisodeListClient {
|
||||
|
||||
private Map<String, URL> cache = Collections.synchronizedMap(new TreeMap<String, URL>());
|
||||
private Map<String, URL> cache = Collections.synchronizedMap(new HashMap<String, URL>());
|
||||
|
||||
private String host = "www.tv.com";
|
||||
|
||||
|
@ -96,8 +96,8 @@ public class TvdotcomClient extends EpisodeListClient {
|
|||
episodeOffset = 0;
|
||||
|
||||
for (Node node : nodes) {
|
||||
String episodeNumber = XPathUtil.selectString("./TD[1]/text()", node);
|
||||
String title = XPathUtil.selectString("./TD[2]/A/text()", node);
|
||||
String episodeNumber = XPathUtil.selectString("./TD[1]", node);
|
||||
String title = XPathUtil.selectString("./TD[2]/A", node);
|
||||
|
||||
try {
|
||||
// format number of episode
|
||||
|
|
|
@ -8,7 +8,6 @@ import java.awt.Component;
|
|||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Paint;
|
||||
import java.awt.RadialGradientPaint;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Shape;
|
||||
|
@ -29,13 +28,15 @@ public class FancyBorder implements Border {
|
|||
private float radius;
|
||||
|
||||
|
||||
public FancyBorder(int width, Color color) {
|
||||
public FancyBorder(int width, Color... colors) {
|
||||
this.borderWidth = width;
|
||||
|
||||
float[] dist = { 0, 1 };
|
||||
this.dist = dist;
|
||||
this.dist = new float[colors.length];
|
||||
|
||||
for (int i = 0; i < colors.length; i++) {
|
||||
this.dist[i] = (1.0f / colors.length) * i;
|
||||
}
|
||||
|
||||
Color[] colors = { color.brighter(), color };
|
||||
this.colors = colors;
|
||||
|
||||
this.radius = 100;
|
||||
|
@ -52,7 +53,9 @@ public class FancyBorder implements Border {
|
|||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c) {
|
||||
return new Insets(borderWidth, borderWidth, borderWidth, borderWidth);
|
||||
|
||||
int horizontalOffset = 8;
|
||||
return new Insets(borderWidth, borderWidth + horizontalOffset, borderWidth, borderWidth + horizontalOffset);
|
||||
}
|
||||
|
||||
|
||||
|
@ -66,19 +69,17 @@ public class FancyBorder implements Border {
|
|||
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
|
||||
Graphics2D g2d = (Graphics2D) g;
|
||||
|
||||
Shape shape = new RoundRectangle2D.Double(x, y, width, height, 10, 10);
|
||||
float arch = Math.min(width, height) / 2;
|
||||
|
||||
Shape shape = new RoundRectangle2D.Float(x + borderWidth, y + borderWidth, width - borderWidth * 2, height - borderWidth * 2, arch, arch);
|
||||
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g2d.setPaint(getPaint(x, y, width, height));
|
||||
|
||||
Point2D center = new Point2D.Float(width, 0);
|
||||
g2d.setPaint(new RadialGradientPaint(center, radius, dist, colors, CycleMethod.REFLECT));
|
||||
|
||||
g2d.setStroke(new BasicStroke(borderWidth));
|
||||
|
||||
g2d.draw(shape);
|
||||
}
|
||||
|
||||
|
||||
private Paint getPaint(int x, int y, int width, int height) {
|
||||
Point2D center = new Point2D.Float(width, 0);
|
||||
|
||||
return new RadialGradientPaint(center, radius, dist, colors, CycleMethod.REFLECT);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,31 +106,16 @@ public class FancyListCellRenderer extends DefaultListCellRenderer {
|
|||
}
|
||||
|
||||
|
||||
public Color getGradientBeginColor() {
|
||||
return gradientBeginColor;
|
||||
}
|
||||
|
||||
|
||||
public void setGradientBeginColor(Color gradientBeginColor) {
|
||||
this.gradientBeginColor = gradientBeginColor;
|
||||
}
|
||||
|
||||
|
||||
public Color getGradientEndColor() {
|
||||
return gradientEndColor;
|
||||
}
|
||||
|
||||
|
||||
public void setGradientEndColor(Color gradientEndColor) {
|
||||
this.gradientEndColor = gradientEndColor;
|
||||
}
|
||||
|
||||
|
||||
public GradientStyle getGradientStyle() {
|
||||
return gradientStyle;
|
||||
}
|
||||
|
||||
|
||||
public void setGradientStyle(GradientStyle gradientStyle) {
|
||||
this.gradientStyle = gradientStyle;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ public class LoadingOverlayPanel extends JPanel {
|
|||
|
||||
loadingLabel.setIcon(animation);
|
||||
loadingLabel.setOpaque(false);
|
||||
loadingLabel.setBorder(BorderFactory.createEmptyBorder(12, 0, 0, 16));
|
||||
loadingLabel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 20));
|
||||
|
||||
loadingLabel.setAlignmentX(1.0f);
|
||||
loadingLabel.setAlignmentY(0.0f);
|
||||
|
|
|
@ -122,4 +122,5 @@ public class SimpleListModel extends AbstractListModel {
|
|||
fireContentsChanged(this, 0, end);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue