* make all file choosers compatible with the mas sandbox
This commit is contained in:
parent
95c8496bfb
commit
88008a2b0f
13
build.xml
13
build.xml
@ -248,8 +248,7 @@
|
||||
|
||||
<option value="-Xdock:name=${title}" />
|
||||
<option value="-Xdock:icon=Contents/Resources/filebot.icns" />
|
||||
<option value="-Dcom.apple.macos.use-file-dialog-packages=true" />
|
||||
<option value="-Dcom.apple.macos.useScreenMenuBar=true" />
|
||||
<option value="-Dapple.laf.useScreenMenuBar=true" />
|
||||
</bundleapp>
|
||||
|
||||
<!-- application bundle folder as .tar.gz -->
|
||||
@ -280,11 +279,9 @@
|
||||
<option value="-Dapplication.cache=./Library/Caches/ehcache.disk.store" />
|
||||
<option value="-Djava.io.tmpdir=./Library/Caches/java.io.tmpdir" />
|
||||
|
||||
<!-- FULL DIRECTORY ACCESS when processing files in the sandbox -->
|
||||
<option value="-Dapple.awt.fileDialogForDirectories=true" />
|
||||
|
||||
<option value="-Dapplication.deployment=mas" />
|
||||
<option value="-Dapplication.update=skip" />
|
||||
<option value="-Dapplication.analytics=false" />
|
||||
<option value="-Dunixfs=false" />
|
||||
<option value="-DuseExtendedFileAttributes=true" />
|
||||
<option value="-DuseCreationDate=false" />
|
||||
@ -301,8 +298,10 @@
|
||||
|
||||
<option value="-Xdock:name=${title}" />
|
||||
<option value="-Xdock:icon=Contents/Resources/filebot.icns" />
|
||||
<option value="-Dcom.apple.macos.use-file-dialog-packages=true" />
|
||||
<option value="-Dcom.apple.macos.useScreenMenuBar=true" />
|
||||
<option value="-Dapple.laf.useScreenMenuBar=true" />
|
||||
|
||||
<argument value="--log-file" />
|
||||
<argument value="filebot.log" />
|
||||
</bundleapp>
|
||||
</target>
|
||||
|
||||
|
@ -5,6 +5,7 @@ import static net.filebot.util.XPathUtilities.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@ -30,7 +31,7 @@ public class MediaTypes {
|
||||
private static MediaTypes parseDefault() {
|
||||
try {
|
||||
Document dom = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(MediaTypes.class.getResourceAsStream("media.types"));
|
||||
Map<String, List<String>> types = new HashMap<String, List<String>>();
|
||||
Map<String, List<String>> types = new LinkedHashMap<String, List<String>>();
|
||||
|
||||
for (Node it : getChildren("type", dom.getFirstChild())) {
|
||||
List<String> extensions = new ArrayList<String>(2);
|
||||
@ -94,6 +95,14 @@ public class MediaTypes {
|
||||
return getDefault().getFilter(name);
|
||||
}
|
||||
|
||||
public static ExtensionFileFilter combineFilter(ExtensionFileFilter... filters) {
|
||||
List<String> extensions = new ArrayList<String>();
|
||||
for (ExtensionFileFilter it : filters) {
|
||||
addAll(extensions, it.extensions());
|
||||
}
|
||||
return new ExtensionFileFilter(extensions);
|
||||
}
|
||||
|
||||
// some convenience filters
|
||||
public static final ExtensionFileFilter AUDIO_FILES = getDefaultFilter("audio");
|
||||
public static final ExtensionFileFilter VIDEO_FILES = getDefaultFilter("video");
|
||||
|
@ -63,7 +63,7 @@ public final class Settings {
|
||||
}
|
||||
|
||||
public static boolean isSandboxed() {
|
||||
return "mas".equals(System.getProperty("application.deployment"));
|
||||
return "mas".equals(getApplicationDeployment());
|
||||
}
|
||||
|
||||
public static int getPreferredThreadPoolSize() {
|
||||
|
@ -6,7 +6,6 @@ import static net.filebot.util.FileUtilities.*;
|
||||
import static net.filebot.util.ui.TunedUtilities.*;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.io.File;
|
||||
@ -22,7 +21,6 @@ import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.ListSelectionModel;
|
||||
@ -31,6 +29,7 @@ import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.TableModel;
|
||||
|
||||
import net.filebot.ResourceManager;
|
||||
import net.filebot.Settings;
|
||||
import net.filebot.archive.Archive;
|
||||
import net.filebot.archive.FileMapper;
|
||||
import net.filebot.util.FileUtilities;
|
||||
@ -110,21 +109,15 @@ class ExtractTool extends Tool<TableModel> {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
final List<File> archives = ((ArchiveEntryModel) table.getModel()).getArchiveList();
|
||||
if (archives.isEmpty()) {
|
||||
if (archives.isEmpty())
|
||||
return;
|
||||
}
|
||||
|
||||
Window window = getWindow(evt.getSource());
|
||||
JFileChooser chooser = new JFileChooser(archives.get(0).getParentFile());
|
||||
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||
chooser.setMultiSelectionEnabled(false);
|
||||
if (chooser.showSaveDialog(window) != JFileChooser.APPROVE_OPTION) {
|
||||
File selectedFile = showOpenDialogSelectFolder(archives.get(0).getParentFile(), "Extract to ...", evt.getSource(), Settings.isSandboxed());
|
||||
if (selectedFile == null)
|
||||
return;
|
||||
}
|
||||
|
||||
final ExtractJob job = new ExtractJob(archives, chooser.getSelectedFile());
|
||||
|
||||
final ProgressDialog dialog = new ProgressDialog(window, job);
|
||||
final ExtractJob job = new ExtractJob(archives, selectedFile);
|
||||
final ProgressDialog dialog = new ProgressDialog(getWindow(evt.getSource()), job);
|
||||
dialog.setLocation(getOffsetLocation(dialog.getOwner()));
|
||||
dialog.setTitle("Extracting files...");
|
||||
dialog.setIcon((Icon) getValue(SMALL_ICON));
|
||||
|
@ -91,7 +91,7 @@ class FileTreeTransferablePolicy extends BackgroundFileTransferablePolicy<TreeNo
|
||||
|
||||
@Override
|
||||
public String getFileFilterDescription() {
|
||||
return "folders";
|
||||
return "Folders";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ class FileListTransferablePolicy extends FileTransferablePolicy {
|
||||
|
||||
@Override
|
||||
public String getFileFilterDescription() {
|
||||
return "files, folders and torrents";
|
||||
return "Files, Folders and Torrents";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,7 +15,6 @@ import java.text.Format;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@ -33,7 +32,6 @@ import javax.swing.Action;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
@ -44,13 +42,13 @@ import javax.swing.RowFilter;
|
||||
import javax.swing.SwingWorker;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.TableModel;
|
||||
import javax.swing.table.TableRowSorter;
|
||||
|
||||
import net.filebot.ResourceManager;
|
||||
import net.filebot.Settings;
|
||||
import net.filebot.format.ExpressionFormat;
|
||||
import net.filebot.format.MediaBindingBean;
|
||||
import net.filebot.media.MediaDetection;
|
||||
@ -58,6 +56,7 @@ import net.filebot.mediainfo.MediaInfo;
|
||||
import net.filebot.mediainfo.MediaInfo.StreamKind;
|
||||
import net.filebot.mediainfo.MediaInfoException;
|
||||
import net.filebot.util.DefaultThreadFactory;
|
||||
import net.filebot.util.FileUtilities.ExtensionFileFilter;
|
||||
import net.filebot.util.ui.LazyDocumentListener;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
@ -351,31 +350,19 @@ class BindingDialog extends JDialog {
|
||||
|
||||
};
|
||||
|
||||
protected final Action selectFileAction = new AbstractAction("Select File", ResourceManager.getIcon("action.load")) {
|
||||
protected final Action selectFileAction = new AbstractAction("Select Media File", ResourceManager.getIcon("action.load")) {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
chooser.setSelectedFile(getMediaFile());
|
||||
ExtensionFileFilter mediaFiles = combineFilter(VIDEO_FILES, AUDIO_FILES, SUBTITLE_FILES);
|
||||
File[] file = showLoadDialogSelectFiles(false, false, getMediaFile(), mediaFiles, (String) getValue(NAME), evt.getSource(), Settings.isSandboxed());
|
||||
|
||||
// collect media file extensions (video, audio and subtitle files)
|
||||
List<String> extensions = new ArrayList<String>();
|
||||
Collections.addAll(extensions, VIDEO_FILES.extensions());
|
||||
Collections.addAll(extensions, AUDIO_FILES.extensions());
|
||||
Collections.addAll(extensions, SUBTITLE_FILES.extensions());
|
||||
|
||||
chooser.setFileFilter(new FileNameExtensionFilter("Media files", extensions.toArray(new String[0])));
|
||||
chooser.setMultiSelectionEnabled(false);
|
||||
|
||||
if (chooser.showOpenDialog(getWindow(evt.getSource())) == JFileChooser.APPROVE_OPTION) {
|
||||
if (file.length > 0) {
|
||||
// update text field
|
||||
File file = chooser.getSelectedFile();
|
||||
|
||||
// set file
|
||||
mediaFileTextField.setText(file.getAbsolutePath());
|
||||
mediaFileTextField.setText(file[0].getAbsolutePath());
|
||||
|
||||
// set info object from xattr if possible
|
||||
Object object = MediaDetection.readMetaInfo(file);
|
||||
Object object = MediaDetection.readMetaInfo(file[0]);
|
||||
if (object != null && infoObjectFormat.format(object) != null) {
|
||||
setInfoObject(object);
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ class FilesListTransferablePolicy extends BackgroundFileTransferablePolicy<File>
|
||||
|
||||
@Override
|
||||
public String getFileFilterDescription() {
|
||||
return "files and folders";
|
||||
return "Files and Folders";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -5,6 +5,7 @@ import static java.util.Collections.*;
|
||||
import static java.util.regex.Pattern.*;
|
||||
import static javax.swing.JOptionPane.*;
|
||||
import static net.filebot.util.FileUtilities.*;
|
||||
import static net.filebot.util.ui.TunedUtilities.*;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
@ -39,7 +40,6 @@ import javax.swing.DefaultListCellRenderer;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JOptionPane;
|
||||
@ -459,7 +459,7 @@ class HistoryDialog extends JDialog {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
List<Element> elements = elements();
|
||||
if (elements.isEmpty())
|
||||
return;
|
||||
@ -515,13 +515,7 @@ class HistoryDialog extends JDialog {
|
||||
|
||||
// change directory option
|
||||
if (selectedOption == Option.ChangeDirectory) {
|
||||
JFileChooser chooser = new JFileChooser(directory);
|
||||
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||
chooser.setMultiSelectionEnabled(false);
|
||||
|
||||
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
|
||||
directory = chooser.getSelectedFile();
|
||||
}
|
||||
directory = showOpenDialogSelectFolder(directory, selectedOption.toString(), evt.getSource(), Settings.isSandboxed());
|
||||
}
|
||||
}
|
||||
|
||||
@ -625,7 +619,7 @@ class HistoryDialog extends JDialog {
|
||||
|
||||
@Override
|
||||
public String getFileFilterDescription() {
|
||||
return "history files (.xml)";
|
||||
return "History Files (.xml)";
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -152,7 +152,7 @@ class NamesListTransferablePolicy extends FileTransferablePolicy {
|
||||
|
||||
@Override
|
||||
public String getFileFilterDescription() {
|
||||
return "text files, verification files, torrent files";
|
||||
return "Text Files, Verification Files, Torrent Files";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -168,7 +168,7 @@ class ChecksumTableTransferablePolicy extends BackgroundFileTransferablePolicy<C
|
||||
|
||||
@Override
|
||||
public String getFileFilterDescription() {
|
||||
return "files, folders and sfv files";
|
||||
return "Files, Folders and SFV Files";
|
||||
}
|
||||
|
||||
private static class VerificationTracker {
|
||||
|
@ -1,7 +1,5 @@
|
||||
|
||||
package net.filebot.ui.subtitle;
|
||||
|
||||
|
||||
import static javax.swing.BorderFactory.*;
|
||||
|
||||
import java.awt.Color;
|
||||
@ -15,17 +13,15 @@ import javax.swing.plaf.basic.ComboPopup;
|
||||
|
||||
import net.filebot.ResourceManager;
|
||||
|
||||
|
||||
public class SimpleComboBox extends JComboBox {
|
||||
|
||||
|
||||
public SimpleComboBox() {
|
||||
setUI(new SimpleComboBoxUI());
|
||||
setBorder(createEmptyBorder());
|
||||
}
|
||||
|
||||
|
||||
private static class SimpleComboBoxUI extends BasicComboBoxUI {
|
||||
|
||||
|
||||
@Override
|
||||
protected JButton createArrowButton() {
|
||||
JButton button = new JButton(ResourceManager.getIcon("arrow.down"));
|
||||
@ -33,38 +29,37 @@ public class SimpleComboBox extends JComboBox {
|
||||
button.setBorderPainted(false);
|
||||
button.setFocusPainted(false);
|
||||
button.setOpaque(false);
|
||||
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected ComboPopup createPopup() {
|
||||
return new BasicComboPopup(comboBox) {
|
||||
|
||||
|
||||
@Override
|
||||
protected Rectangle computePopupBounds(int px, int py, int pw, int ph) {
|
||||
Rectangle bounds = super.computePopupBounds(px, py, pw, ph);
|
||||
|
||||
|
||||
// allow combobox popup to be wider than the combobox itself
|
||||
bounds.width = Math.max(bounds.width, list.getPreferredSize().width);
|
||||
|
||||
|
||||
return bounds;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void configurePopup() {
|
||||
super.configurePopup();
|
||||
|
||||
|
||||
setOpaque(true);
|
||||
setBackground(list.getBackground());
|
||||
|
||||
list.setBackground(Color.white);
|
||||
setBackground(Color.white);
|
||||
|
||||
// use gray instead of black border for combobox popup
|
||||
setBorder(createCompoundBorder(createLineBorder(Color.gray, 1), createEmptyBorder(1, 1, 1, 1)));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ import java.util.logging.Logger;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.DefaultCellEditor;
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.DefaultListCellRenderer;
|
||||
@ -168,6 +169,7 @@ class SubtitleAutoMatchDialog extends JDialog {
|
||||
|
||||
protected void addSubtitleService(final SubtitleServiceBean service, final JPanel servicePanel) {
|
||||
final LinkButton component = new LinkButton(service.getName(), ResourceManager.getIcon("database"), service.getLink());
|
||||
component.setBorder(BorderFactory.createEmptyBorder());
|
||||
component.setVisible(false);
|
||||
|
||||
service.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
@ -351,6 +353,7 @@ class SubtitleAutoMatchDialog extends JDialog {
|
||||
private final JComboBox optionComboBox = new SimpleComboBox();
|
||||
|
||||
public SubtitleMappingOptionRenderer() {
|
||||
optionComboBox.setBackground(Color.white);
|
||||
optionComboBox.setRenderer(new SubtitleOptionRenderer(false));
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
|
||||
package net.filebot.ui.subtitle;
|
||||
|
||||
|
||||
import static net.filebot.MediaTypes.*;
|
||||
import static net.filebot.subtitle.SubtitleUtilities.*;
|
||||
import static net.filebot.ui.NotificationLogging.*;
|
||||
@ -17,6 +15,7 @@ import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CancellationException;
|
||||
@ -41,6 +40,7 @@ import javax.swing.border.LineBorder;
|
||||
|
||||
import net.filebot.Analytics;
|
||||
import net.filebot.ResourceManager;
|
||||
import net.filebot.Settings;
|
||||
import net.filebot.subtitle.SubtitleFormat;
|
||||
import net.filebot.ui.subtitle.SubtitlePackage.Download.Phase;
|
||||
import net.filebot.ui.transfer.DefaultTransferHandler;
|
||||
@ -62,180 +62,169 @@ import ca.odell.glazedlists.swing.EventListModel;
|
||||
import ca.odell.glazedlists.swing.EventSelectionModel;
|
||||
import ca.odell.glazedlists.swing.TextComponentMatcherEditor;
|
||||
|
||||
|
||||
class SubtitleDownloadComponent extends JComponent {
|
||||
|
||||
|
||||
private EventList<SubtitlePackage> packages = new BasicEventList<SubtitlePackage>();
|
||||
|
||||
|
||||
private EventList<MemoryFile> files = new BasicEventList<MemoryFile>();
|
||||
|
||||
|
||||
private SubtitlePackageCellRenderer renderer = new SubtitlePackageCellRenderer();
|
||||
|
||||
|
||||
private JTextField filterEditor = new JTextField();
|
||||
|
||||
|
||||
|
||||
public SubtitleDownloadComponent() {
|
||||
final JList packageList = new JList(createPackageListModel());
|
||||
packageList.setFixedCellHeight(32);
|
||||
packageList.setCellRenderer(renderer);
|
||||
|
||||
|
||||
// better selection behaviour
|
||||
EventSelectionModel<SubtitlePackage> packageSelection = new EventSelectionModel<SubtitlePackage>(packages);
|
||||
packageSelection.setSelectionMode(ListSelection.MULTIPLE_INTERVAL_SELECTION_DEFENSIVE);
|
||||
packageList.setSelectionModel(packageSelection);
|
||||
|
||||
|
||||
// context menu and fetch on double click
|
||||
packageList.addMouseListener(packageListMouseHandler);
|
||||
|
||||
|
||||
// file list view
|
||||
final JList fileList = new ListView(createFileListModel()) {
|
||||
|
||||
|
||||
@Override
|
||||
protected String convertValueToText(Object value) {
|
||||
MemoryFile file = (MemoryFile) value;
|
||||
return file.getName();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected Icon convertValueToIcon(Object value) {
|
||||
if (SUBTITLE_FILES.accept(value.toString()))
|
||||
return ResourceManager.getIcon("file.subtitle");
|
||||
|
||||
|
||||
return ResourceManager.getIcon("file.unknown");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// better selection behaviour
|
||||
EventSelectionModel<MemoryFile> fileSelection = new EventSelectionModel<MemoryFile>(files);
|
||||
fileSelection.setSelectionMode(ListSelection.MULTIPLE_INTERVAL_SELECTION_DEFENSIVE);
|
||||
fileList.setSelectionModel(fileSelection);
|
||||
|
||||
|
||||
// install dnd and clipboard export handler
|
||||
MemoryFileListExportHandler memoryFileExportHandler = new MemoryFileListExportHandler();
|
||||
fileList.setTransferHandler(new DefaultTransferHandler(null, memoryFileExportHandler, memoryFileExportHandler));
|
||||
|
||||
|
||||
fileList.setDragEnabled(true);
|
||||
fileList.addMouseListener(fileListMouseHandler);
|
||||
|
||||
|
||||
JButton clearButton = new JButton(clearFilterAction);
|
||||
clearButton.setOpaque(false);
|
||||
|
||||
|
||||
setLayout(new MigLayout("nogrid, fill", "[fill]", "[pref!][fill]"));
|
||||
|
||||
|
||||
add(new JLabel("Filter:"), "gap indent:push");
|
||||
add(filterEditor, "wmin 120px, gap rel");
|
||||
add(clearButton, "w 24px!, h 24px!");
|
||||
add(new JScrollPane(packageList), "newline, hmin 80px");
|
||||
|
||||
|
||||
JScrollPane scrollPane = new JScrollPane(fileList);
|
||||
scrollPane.setViewportBorder(new LineBorder(fileList.getBackground()));
|
||||
add(scrollPane, "newline, hmin max(80px, 30%)");
|
||||
|
||||
|
||||
// install fetch action
|
||||
TunedUtilities.installAction(packageList, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), new AbstractAction("Fetch") {
|
||||
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
fetch(packageList.getSelectedValues());
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// install open action
|
||||
TunedUtilities.installAction(fileList, KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), new AbstractAction("Open") {
|
||||
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
open(fileList.getSelectedValues());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected ListModel createPackageListModel() {
|
||||
// allow filtering by language name and subtitle name
|
||||
MatcherEditor<SubtitlePackage> matcherEditor = new TextComponentMatcherEditor<SubtitlePackage>(filterEditor, new TextFilterator<SubtitlePackage>() {
|
||||
|
||||
|
||||
@Override
|
||||
public void getFilterStrings(List<String> list, SubtitlePackage element) {
|
||||
list.add(element.getLanguage().getName());
|
||||
list.add(element.getName());
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// source list
|
||||
EventList<SubtitlePackage> source = getPackageModel();
|
||||
|
||||
|
||||
// filter list
|
||||
source = new FilterList<SubtitlePackage>(source, matcherEditor);
|
||||
|
||||
|
||||
// listen to changes (e.g. download progress)
|
||||
source = new ObservableElementList<SubtitlePackage>(source, GlazedLists.beanConnector(SubtitlePackage.class));
|
||||
|
||||
|
||||
// as list model
|
||||
return new EventListModel<SubtitlePackage>(source);
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected ListModel createFileListModel() {
|
||||
// source list
|
||||
EventList<MemoryFile> source = getFileModel();
|
||||
|
||||
|
||||
// sort by name
|
||||
source = new SortedList<MemoryFile>(source, new Comparator<MemoryFile>() {
|
||||
|
||||
|
||||
@Override
|
||||
public int compare(MemoryFile m1, MemoryFile m2) {
|
||||
return m1.getName().compareToIgnoreCase(m2.getName());
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// as list model
|
||||
return new EventListModel<MemoryFile>(source);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void reset() {
|
||||
// cancel and reset download workers
|
||||
for (SubtitlePackage subtitle : packages) {
|
||||
subtitle.reset();
|
||||
}
|
||||
|
||||
|
||||
files.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public EventList<SubtitlePackage> getPackageModel() {
|
||||
return packages;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public EventList<MemoryFile> getFileModel() {
|
||||
return files;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setLanguageVisible(boolean visible) {
|
||||
renderer.getLanguageLabel().setVisible(visible);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void fetch(Object[] selection) {
|
||||
for (Object value : selection) {
|
||||
fetch((SubtitlePackage) value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void fetch(final SubtitlePackage subtitle) {
|
||||
if (subtitle.getDownload().isStarted()) {
|
||||
// download has been started already
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// listen to download
|
||||
subtitle.addPropertyChangeListener(new PropertyChangeListener() {
|
||||
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (evt.getNewValue() == Phase.DONE) {
|
||||
@ -247,27 +236,26 @@ class SubtitleDownloadComponent extends JComponent {
|
||||
// ignore cancellation
|
||||
} catch (Exception e) {
|
||||
UILogger.log(Level.WARNING, ExceptionUtilities.getRootCauseMessage(e), e);
|
||||
|
||||
|
||||
// reset download
|
||||
subtitle.reset();
|
||||
}
|
||||
|
||||
|
||||
// listener no longer required
|
||||
subtitle.removePropertyChangeListener(this);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// enqueue worker
|
||||
subtitle.getDownload().start();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void open(Object[] selection) {
|
||||
try {
|
||||
for (Object object : selection) {
|
||||
MemoryFile file = (MemoryFile) object;
|
||||
|
||||
|
||||
// only open subtitle files
|
||||
if (SUBTITLE_FILES.accept(file.getName())) {
|
||||
open(file);
|
||||
@ -277,248 +265,222 @@ class SubtitleDownloadComponent extends JComponent {
|
||||
UILogger.log(Level.WARNING, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void open(MemoryFile file) throws IOException {
|
||||
SubtitleViewer viewer = new SubtitleViewer(file.getName());
|
||||
viewer.getTitleLabel().setText("Subtitle Viewer");
|
||||
viewer.getInfoLabel().setText(file.getPath());
|
||||
|
||||
|
||||
viewer.setData(decodeSubtitles(file));
|
||||
viewer.setVisible(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void save(Object[] selection) {
|
||||
try {
|
||||
if (selection.length == 1) {
|
||||
// single file
|
||||
MemoryFile file = (MemoryFile) selection[0];
|
||||
|
||||
JFileChooser fc = new JFileChooser();
|
||||
fc.setSelectedFile(new File(validateFileName(file.getName())));
|
||||
|
||||
if (fc.showSaveDialog(getWindow(this)) == JFileChooser.APPROVE_OPTION) {
|
||||
writeFile(file.getData(), fc.getSelectedFile());
|
||||
}
|
||||
} else {
|
||||
// multiple files
|
||||
JFileChooser fc = new JFileChooser();
|
||||
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||
|
||||
if (fc.showSaveDialog(getWindow(this)) == JFileChooser.APPROVE_OPTION) {
|
||||
File folder = fc.getSelectedFile();
|
||||
|
||||
for (Object object : selection) {
|
||||
MemoryFile file = (MemoryFile) object;
|
||||
File destination = new File(folder, validateFileName(file.getName()));
|
||||
writeFile(file.getData(), destination);
|
||||
}
|
||||
// multiple files
|
||||
File outputFolder = showOpenDialogSelectFolder(null, "Save Subtitles", this, Settings.isSandboxed());
|
||||
if (outputFolder != null) {
|
||||
for (Object object : selection) {
|
||||
MemoryFile file = (MemoryFile) object;
|
||||
File destination = new File(outputFolder, validateFileName(file.getName()));
|
||||
writeFile(file.getData(), destination);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
} catch (Exception e) {
|
||||
UILogger.log(Level.WARNING, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void export(Object[] selection) {
|
||||
|
||||
try {
|
||||
if (selection.length == 1) {
|
||||
// single file
|
||||
MemoryFile file = (MemoryFile) selection[0];
|
||||
|
||||
SubtitleFileChooser sf = new SubtitleFileChooser();
|
||||
|
||||
// normalize name and auto-adjust extension
|
||||
String ext = sf.getSelectedFormat().getFilter().extension();
|
||||
String name = validateFileName(getNameWithoutExtension(file.getName()));
|
||||
sf.setSelectedFile(new File(name + "." + ext));
|
||||
|
||||
if (sf.showSaveDialog(getWindow(this)) == JFileChooser.APPROVE_OPTION) {
|
||||
SubtitleFormat targetFormat = sf.getSelectedFormat().getFilter().accept(file.getName()) ? null : sf.getSelectedFormat();
|
||||
writeFile(exportSubtitles(file, targetFormat, sf.getTimingOffset(), sf.getSelectedEncoding()), sf.getSelectedFile());
|
||||
}
|
||||
File selectedOutputFolder = null;
|
||||
|
||||
// default values
|
||||
SubtitleFormat selectedFormat = SubtitleFormat.SubRip;
|
||||
long selectedTimingOffset = 0;
|
||||
Charset selectedEncoding = Charset.forName("UTF-8");
|
||||
|
||||
// just use default values when we can't use a JFC with accessory component
|
||||
if (Settings.isSandboxed()) {
|
||||
// AWT
|
||||
selectedOutputFolder = showOpenDialogSelectFolder(null, "Export Subtitles", this, Settings.isSandboxed());
|
||||
} else {
|
||||
// multiple files
|
||||
SubtitleFileChooser sf = new SubtitleFileChooser();
|
||||
sf.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||
|
||||
if (sf.showSaveDialog(getWindow(this)) == JFileChooser.APPROVE_OPTION) {
|
||||
File folder = sf.getSelectedFile();
|
||||
|
||||
for (Object object : selection) {
|
||||
MemoryFile file = (MemoryFile) object;
|
||||
|
||||
// normalize name and auto-adjust extension
|
||||
String ext = sf.getSelectedFormat().getFilter().extension();
|
||||
String name = validateFileName(getNameWithoutExtension(file.getName()));
|
||||
File destination = new File(folder, name + "." + ext);
|
||||
|
||||
SubtitleFormat targetFormat = sf.getSelectedFormat().getFilter().accept(file.getName()) ? null : sf.getSelectedFormat();
|
||||
writeFile(exportSubtitles(file, targetFormat, sf.getTimingOffset(), sf.getSelectedEncoding()), destination);
|
||||
}
|
||||
// Swing
|
||||
SubtitleFileChooser sfc = new SubtitleFileChooser();
|
||||
sfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||
if (sfc.showSaveDialog(getWindow(this)) == JFileChooser.APPROVE_OPTION) {
|
||||
selectedOutputFolder = sfc.getSelectedFile();
|
||||
selectedFormat = sfc.getSelectedFormat();
|
||||
selectedTimingOffset = sfc.getTimingOffset();
|
||||
selectedEncoding = sfc.getSelectedEncoding();
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
||||
if (selectedOutputFolder != null) {
|
||||
for (Object object : selection) {
|
||||
MemoryFile file = (MemoryFile) object;
|
||||
|
||||
// normalize name and auto-adjust extension
|
||||
String name = validateFileName(getNameWithoutExtension(file.getName()));
|
||||
File destination = new File(selectedOutputFolder, name + "." + selectedFormat.getFilter().extension());
|
||||
|
||||
SubtitleFormat targetFormat = selectedFormat.getFilter().accept(file.getName()) ? null : selectedFormat; // check if format conversion is necessary
|
||||
writeFile(exportSubtitles(file, targetFormat, selectedTimingOffset, selectedEncoding), destination);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
UILogger.log(Level.WARNING, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private final Action clearFilterAction = new AbstractAction(null, ResourceManager.getIcon("edit.clear")) {
|
||||
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
filterEditor.setText("");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private final MouseListener packageListMouseHandler = new MouseAdapter() {
|
||||
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
// fetch on double click
|
||||
if (SwingUtilities.isLeftMouseButton(e) && (e.getClickCount() == 2)) {
|
||||
JList list = (JList) e.getSource();
|
||||
|
||||
|
||||
fetch(list.getSelectedValues());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
maybeShowPopup(e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
maybeShowPopup(e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void maybeShowPopup(MouseEvent e) {
|
||||
if (e.isPopupTrigger()) {
|
||||
JList list = (JList) e.getSource();
|
||||
|
||||
|
||||
int index = list.locationToIndex(e.getPoint());
|
||||
|
||||
|
||||
if (index >= 0 && !list.isSelectedIndex(index)) {
|
||||
// auto-select clicked element
|
||||
list.setSelectedIndex(index);
|
||||
}
|
||||
|
||||
|
||||
final Object[] selection = list.getSelectedValues();
|
||||
|
||||
|
||||
if (selection.length > 0) {
|
||||
JPopupMenu contextMenu = new JPopupMenu();
|
||||
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private boolean isPending(Object[] selection) {
|
||||
for (Object value : selection) {
|
||||
SubtitlePackage subtitle = (SubtitlePackage) value;
|
||||
|
||||
|
||||
if (!subtitle.getDownload().isStarted()) {
|
||||
// pending download found
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private final MouseListener fileListMouseHandler = new MouseAdapter() {
|
||||
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
// open on double click
|
||||
if (SwingUtilities.isLeftMouseButton(e) && (e.getClickCount() == 2)) {
|
||||
JList list = (JList) e.getSource();
|
||||
|
||||
|
||||
// open selection
|
||||
open(list.getSelectedValues());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
maybeShowPopup(e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
maybeShowPopup(e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void maybeShowPopup(MouseEvent e) {
|
||||
if (e.isPopupTrigger()) {
|
||||
JList list = (JList) e.getSource();
|
||||
|
||||
|
||||
int index = list.locationToIndex(e.getPoint());
|
||||
|
||||
|
||||
if (index >= 0 && !list.isSelectedIndex(index)) {
|
||||
// auto-select clicked element
|
||||
list.setSelectedIndex(index);
|
||||
}
|
||||
|
||||
|
||||
final Object[] selection = list.getSelectedValues();
|
||||
|
||||
|
||||
if (selection.length > 0) {
|
||||
JPopupMenu contextMenu = new JPopupMenu();
|
||||
|
||||
|
||||
// Open
|
||||
contextMenu.add(new AbstractAction("Open") {
|
||||
|
||||
contextMenu.add(new AbstractAction("Preview", ResourceManager.getIcon("action.find")) {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
open(selection);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Save As...
|
||||
contextMenu.add(new AbstractAction("Save As...", ResourceManager.getIcon("action.save")) {
|
||||
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
save(selection);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Export...
|
||||
contextMenu.add(new AbstractAction("Export...", ResourceManager.getIcon("action.export")) {
|
||||
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
export(selection);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
contextMenu.show(e.getComponent(), e.getX(), e.getY());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.filebot.ui.subtitle;
|
||||
|
||||
import static java.util.Arrays.*;
|
||||
import static net.filebot.MediaTypes.*;
|
||||
import static net.filebot.media.MediaDetection.*;
|
||||
import static net.filebot.ui.NotificationLogging.*;
|
||||
@ -18,10 +19,7 @@ import java.awt.dnd.DropTargetEvent;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -31,10 +29,9 @@ import java.util.logging.Level;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
|
||||
import net.filebot.ResourceManager;
|
||||
import net.filebot.Settings;
|
||||
import net.filebot.util.FileUtilities;
|
||||
import net.filebot.util.FileUtilities.ParentFilter;
|
||||
import net.filebot.web.OpenSubtitlesClient;
|
||||
@ -130,21 +127,12 @@ abstract class SubtitleDropTarget extends JButton {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
|
||||
chooser.setMultiSelectionEnabled(true);
|
||||
|
||||
// collect media file extensions (video and subtitle files)
|
||||
List<String> extensions = new ArrayList<String>();
|
||||
Collections.addAll(extensions, VIDEO_FILES.extensions());
|
||||
Collections.addAll(extensions, SUBTITLE_FILES.extensions());
|
||||
chooser.setFileFilter(new FileNameExtensionFilter("Media files", extensions.toArray(new String[0])));
|
||||
File[] files = showLoadDialogSelectFiles(true, true, null, combineFilter(VIDEO_FILES, SUBTITLE_FILES), "Select Video Folder", evt.getSource(), Settings.isSandboxed());
|
||||
|
||||
if (chooser.showOpenDialog(getWindow(evt.getSource())) == JFileChooser.APPROVE_OPTION) {
|
||||
List<File> files = Arrays.asList(chooser.getSelectedFiles());
|
||||
|
||||
if (getDropAction(files) != DropAction.Cancel) {
|
||||
handleDrop(Arrays.asList(chooser.getSelectedFiles()));
|
||||
if (files.length > 0) {
|
||||
if (getDropAction(asList(files)) != DropAction.Cancel) {
|
||||
handleDrop(asList(files));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,6 @@ import javax.swing.Icon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JScrollPane;
|
||||
@ -43,7 +42,6 @@ import javax.swing.JTable;
|
||||
import javax.swing.ListCellRenderer;
|
||||
import javax.swing.SwingWorker;
|
||||
import javax.swing.event.CellEditorListener;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.TableCellEditor;
|
||||
@ -52,6 +50,7 @@ import javax.swing.table.TableCellRenderer;
|
||||
import net.filebot.Analytics;
|
||||
import net.filebot.Language;
|
||||
import net.filebot.ResourceManager;
|
||||
import net.filebot.Settings;
|
||||
import net.filebot.WebServices;
|
||||
import net.filebot.media.MediaDetection;
|
||||
import net.filebot.ui.LanguageComboBox;
|
||||
@ -228,16 +227,11 @@ public class SubtitleUploadDialog extends JDialog {
|
||||
SubtitleMappingTableModel model = (SubtitleMappingTableModel) table.getModel();
|
||||
SubtitleMapping mapping = model.getData()[table.convertRowIndexToModel(row)];
|
||||
|
||||
JFileChooser chooser = new JFileChooser(mapping.getSubtitle().getParentFile());
|
||||
chooser.setFileFilter(new FileNameExtensionFilter("Video files", VIDEO_FILES.extensions()));
|
||||
chooser.setMultiSelectionEnabled(false);
|
||||
|
||||
if (chooser.showOpenDialog(getWindow(SubtitleUploadDialog.this)) == JFileChooser.APPROVE_OPTION) {
|
||||
if (chooser.getSelectedFile() != null) {
|
||||
mapping.setVideo(chooser.getSelectedFile());
|
||||
mapping.setState(SubtitleMapping.Status.CheckPending);
|
||||
startChecking();
|
||||
}
|
||||
File[] files = showLoadDialogSelectFiles(false, false, mapping.getSubtitle().getParentFile(), VIDEO_FILES, "Select Video File", getWindow(SubtitleUploadDialog.this), Settings.isSandboxed());
|
||||
if (files.length > 0) {
|
||||
mapping.setVideo(files[0]);
|
||||
mapping.setState(SubtitleMapping.Status.CheckPending);
|
||||
startChecking();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -1,16 +1,15 @@
|
||||
package net.filebot.ui.transfer;
|
||||
|
||||
import static net.filebot.ui.NotificationLogging.*;
|
||||
import static net.filebot.util.ui.TunedUtilities.*;
|
||||
|
||||
import java.awt.FileDialog;
|
||||
import java.awt.Frame;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.io.File;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JFileChooser;
|
||||
|
||||
import net.filebot.ResourceManager;
|
||||
import net.filebot.Settings;
|
||||
@ -56,52 +55,18 @@ public class LoadAction extends AbstractAction {
|
||||
return;
|
||||
}
|
||||
|
||||
File[] files = showSelectFiles(new TransferablePolicyFileFilter(transferablePolicy));
|
||||
File[] files = showLoadDialogSelectFiles(true, true, getDefaultFolder(), new TransferablePolicyFileFilter(transferablePolicy), (String) getValue(Action.NAME), evt.getSource(), Settings.isSandboxed());
|
||||
if (files == null || files.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
FileTransferable transferable = new FileTransferable(files);
|
||||
|
||||
if (transferablePolicy.accept(transferable)) {
|
||||
transferablePolicy.handleTransferable(transferable, getTransferAction(evt));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
UILogger.log(Level.WARNING, e.getMessage(), e);
|
||||
UILogger.log(Level.WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public File[] showSelectFiles(TransferablePolicyFileFilter fileFilter) {
|
||||
if (Settings.isSandboxed()) {
|
||||
Frame[] frames = Frame.getFrames();
|
||||
Frame mainFrame = frames.length > 0 ? frames[0] : null;
|
||||
FileDialog fileDialog = new FileDialog(mainFrame, "", FileDialog.LOAD);
|
||||
|
||||
File currentFolder = getDefaultFolder();
|
||||
if (currentFolder != null) {
|
||||
fileDialog.setDirectory(currentFolder.getPath());
|
||||
}
|
||||
fileDialog.setMultipleMode(true);
|
||||
fileDialog.setVisible(true);
|
||||
|
||||
File[] files = fileDialog.getFiles();
|
||||
if (files.length > 0) {
|
||||
setDefaultFolder(new File(fileDialog.getDirectory()));
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
// use normal Swing JFileChooser by default
|
||||
JFileChooser chooser = new JFileChooser(getDefaultFolder());
|
||||
chooser.setFileFilter(fileFilter);
|
||||
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
|
||||
chooser.setMultiSelectionEnabled(true);
|
||||
|
||||
if (chooser.showOpenDialog(null) != JFileChooser.APPROVE_OPTION) {
|
||||
return null;
|
||||
}
|
||||
|
||||
setDefaultFolder(chooser.getCurrentDirectory());
|
||||
return chooser.getSelectedFiles();
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,7 @@
|
||||
|
||||
package net.filebot.ui.transfer;
|
||||
|
||||
|
||||
import static net.filebot.util.FileUtilities.*;
|
||||
import static net.filebot.util.ui.TunedUtilities.*;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.io.File;
|
||||
@ -11,81 +10,69 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JFileChooser;
|
||||
|
||||
import net.filebot.ResourceManager;
|
||||
import net.filebot.Settings;
|
||||
|
||||
|
||||
public class SaveAction extends AbstractAction {
|
||||
|
||||
|
||||
public static final String EXPORT_HANDLER = "exportHandler";
|
||||
|
||||
|
||||
public SaveAction(FileExportHandler exportHandler) {
|
||||
this("Save as ...", ResourceManager.getIcon("action.save"), exportHandler);
|
||||
}
|
||||
|
||||
|
||||
public SaveAction(String name, Icon icon, FileExportHandler exportHandler) {
|
||||
putValue(NAME, name);
|
||||
putValue(SMALL_ICON, icon);
|
||||
putValue(EXPORT_HANDLER, exportHandler);
|
||||
}
|
||||
|
||||
|
||||
public FileExportHandler getExportHandler() {
|
||||
return (FileExportHandler) getValue(EXPORT_HANDLER);
|
||||
}
|
||||
|
||||
|
||||
protected boolean canExport() {
|
||||
return getExportHandler().canExport();
|
||||
}
|
||||
|
||||
|
||||
protected void export(File file) throws IOException {
|
||||
getExportHandler().export(file);
|
||||
}
|
||||
|
||||
|
||||
protected String getDefaultFileName() {
|
||||
return getExportHandler().getDefaultFileName();
|
||||
}
|
||||
|
||||
|
||||
protected File getDefaultFolder() {
|
||||
String lastLocation = Settings.forPackage(SaveAction.class).get("save.location");
|
||||
|
||||
|
||||
if (lastLocation == null || lastLocation.isEmpty())
|
||||
return null;
|
||||
|
||||
|
||||
return new File(lastLocation);
|
||||
}
|
||||
|
||||
|
||||
protected void setDefaultFolder(File folder) {
|
||||
Settings.forPackage(LoadAction.class).put("save.location", folder.getPath());
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
if (!canExport())
|
||||
return;
|
||||
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
|
||||
chooser.setMultiSelectionEnabled(false);
|
||||
|
||||
chooser.setSelectedFile(new File(getDefaultFolder(), validateFileName(getDefaultFileName())));
|
||||
|
||||
if (chooser.showSaveDialog((JComponent) evt.getSource()) != JFileChooser.APPROVE_OPTION)
|
||||
return;
|
||||
|
||||
try {
|
||||
export(chooser.getSelectedFile());
|
||||
} catch (IOException e) {
|
||||
if (canExport()) {
|
||||
File defaultFile = new File(getDefaultFolder(), validateFileName(getDefaultFileName()));
|
||||
File file = showSaveDialogSelectFile(false, defaultFile, (String) getValue(Action.NAME), evt.getSource(), Settings.isSandboxed());
|
||||
|
||||
if (file != null) {
|
||||
setDefaultFolder(file.getParentFile());
|
||||
export(file);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(getClass().getName()).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
|
||||
// remember last location
|
||||
Settings.forPackage(SaveAction.class).put("save.location", chooser.getCurrentDirectory().getPath());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -32,11 +32,15 @@ public class TransferablePolicyFileFilter extends FileFilter implements Filename
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return this.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (transferablePolicy instanceof FileTransferablePolicy) {
|
||||
return ((FileTransferablePolicy) transferablePolicy).getFileFilterDescription();
|
||||
}
|
||||
|
||||
return null;
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -695,7 +695,7 @@ public final class FileUtilities {
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExtensionFileFilter implements FileFilter {
|
||||
public static class ExtensionFileFilter implements FileFilter, FilenameFilter {
|
||||
|
||||
private final String[] extensions;
|
||||
|
||||
@ -707,6 +707,11 @@ public final class FileUtilities {
|
||||
this.extensions = extensions.toArray(new String[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(File dir, String name) {
|
||||
return hasExtension(name, extensions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(File file) {
|
||||
return hasExtension(file, extensions);
|
||||
@ -732,6 +737,18 @@ public final class FileUtilities {
|
||||
public String[] extensions() {
|
||||
return extensions.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder s = new StringBuilder();
|
||||
for (String it : extensions) {
|
||||
if (s.length() > 0) {
|
||||
s.append(", ");
|
||||
}
|
||||
s.append("*.").append(it);
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class RegexFileFilter implements FileFilter, FilenameFilter {
|
||||
|
@ -5,7 +5,9 @@ import static javax.swing.JOptionPane.*;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dialog;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FileDialog;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
@ -17,6 +19,8 @@ import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -28,6 +32,7 @@ import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.ListSelectionModel;
|
||||
@ -40,7 +45,98 @@ import javax.swing.undo.UndoManager;
|
||||
|
||||
public final class TunedUtilities {
|
||||
|
||||
public static final Color TRANSLUCENT = new Color(255, 255, 255, 0);
|
||||
public static File[] showLoadDialogSelectFiles(boolean folderMode, boolean multiSelection, File defaultFile, final FilenameFilter filter, String title, Object parent, boolean useNative) {
|
||||
if (useNative) {
|
||||
FileDialog fileDialog = createFileDialog(parent, title, FileDialog.LOAD, folderMode);
|
||||
|
||||
if (defaultFile != null) {
|
||||
fileDialog.setFile(defaultFile.getPath());
|
||||
}
|
||||
if (filter != null) {
|
||||
fileDialog.setFilenameFilter(filter);
|
||||
}
|
||||
fileDialog.setMultipleMode(multiSelection);
|
||||
fileDialog.setVisible(true);
|
||||
|
||||
return fileDialog.getFiles();
|
||||
}
|
||||
|
||||
// use normal Swing JFileChooser by default
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
if (filter != null) {
|
||||
chooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return filter.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(File f) {
|
||||
return f.isDirectory() || filter.accept(f.getParentFile(), f.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
chooser.setSelectedFile(defaultFile);
|
||||
chooser.setFileSelectionMode(folderMode && filter == null ? JFileChooser.DIRECTORIES_ONLY : JFileChooser.FILES_AND_DIRECTORIES);
|
||||
chooser.setMultiSelectionEnabled(multiSelection);
|
||||
|
||||
if (chooser.showOpenDialog(getWindow(parent)) == JFileChooser.APPROVE_OPTION) {
|
||||
if (chooser.getSelectedFiles().length > 0)
|
||||
return chooser.getSelectedFiles();
|
||||
if (chooser.getSelectedFile() != null)
|
||||
return new File[] { chooser.getSelectedFile() };
|
||||
}
|
||||
return new File[0];
|
||||
}
|
||||
|
||||
public static File showOpenDialogSelectFolder(File defaultFile, String title, Object parent, boolean useNative) {
|
||||
File[] folder = showLoadDialogSelectFiles(true, false, defaultFile, null, title, parent, useNative);
|
||||
return folder.length > 0 ? folder[0] : null;
|
||||
}
|
||||
|
||||
public static File showSaveDialogSelectFile(boolean folderMode, File defaultFile, String title, Object parent, boolean useNative) {
|
||||
if (useNative) {
|
||||
FileDialog fileDialog = createFileDialog(getWindow(parent), title, FileDialog.SAVE, folderMode);
|
||||
|
||||
if (defaultFile != null) {
|
||||
if (defaultFile.getParentFile() != null) {
|
||||
fileDialog.setDirectory(defaultFile.getParentFile().getPath());
|
||||
}
|
||||
fileDialog.setFile(defaultFile.getName());
|
||||
}
|
||||
fileDialog.setMultipleMode(false);
|
||||
fileDialog.setVisible(true);
|
||||
|
||||
File[] files = fileDialog.getFiles();
|
||||
return files.length > 0 ? files[0] : null;
|
||||
}
|
||||
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
chooser.setSelectedFile(defaultFile);
|
||||
chooser.setFileSelectionMode(folderMode ? JFileChooser.DIRECTORIES_ONLY : JFileChooser.FILES_AND_DIRECTORIES);
|
||||
chooser.setMultiSelectionEnabled(false);
|
||||
|
||||
if (chooser.showSaveDialog(getWindow(parent)) != JFileChooser.APPROVE_OPTION) {
|
||||
return null;
|
||||
}
|
||||
return chooser.getSelectedFile();
|
||||
}
|
||||
|
||||
public static FileDialog createFileDialog(Object parent, String title, int mode, boolean fileDialogForDirectories) {
|
||||
System.setProperty("apple.awt.fileDialogForDirectories", String.valueOf(fileDialogForDirectories));
|
||||
|
||||
if (parent instanceof Frame) {
|
||||
return new FileDialog((Frame) parent, title, mode);
|
||||
}
|
||||
if (parent instanceof Dialog) {
|
||||
return new FileDialog((Dialog) parent, title, mode);
|
||||
}
|
||||
|
||||
Frame[] frames = Frame.getFrames();
|
||||
return new FileDialog(frames.length > 0 ? frames[0] : null, title, mode);
|
||||
}
|
||||
|
||||
public static void checkEventDispatchThread() {
|
||||
if (!SwingUtilities.isEventDispatchThread()) {
|
||||
@ -48,6 +144,8 @@ public final class TunedUtilities {
|
||||
}
|
||||
}
|
||||
|
||||
public static final Color TRANSLUCENT = new Color(255, 255, 255, 0);
|
||||
|
||||
public static Color interpolateHSB(Color c1, Color c2, float f) {
|
||||
float[] hsb1 = Color.RGBtoHSB(c1.getRed(), c1.getGreen(), c1.getBlue(), null);
|
||||
float[] hsb2 = Color.RGBtoHSB(c2.getRed(), c2.getGreen(), c2.getBlue(), null);
|
||||
|
Loading…
Reference in New Issue
Block a user