* make all file choosers compatible with the mas sandbox

This commit is contained in:
Reinhard Pointner 2014-07-28 19:20:55 +00:00
parent 95c8496bfb
commit 88008a2b0f
21 changed files with 346 additions and 351 deletions

View File

@ -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>

View File

@ -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");

View File

@ -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() {

View File

@ -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));

View File

@ -91,7 +91,7 @@ class FileTreeTransferablePolicy extends BackgroundFileTransferablePolicy<TreeNo
@Override
public String getFileFilterDescription() {
return "folders";
return "Folders";
}
}

View File

@ -74,7 +74,7 @@ class FileListTransferablePolicy extends FileTransferablePolicy {
@Override
public String getFileFilterDescription() {
return "files, folders and torrents";
return "Files, Folders and Torrents";
}
}

View File

@ -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);
}

View File

@ -100,7 +100,7 @@ class FilesListTransferablePolicy extends BackgroundFileTransferablePolicy<File>
@Override
public String getFileFilterDescription() {
return "files and folders";
return "Files and Folders";
}
@Override

View File

@ -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)";
}
};

View File

@ -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";
}
}

View File

@ -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 {

View File

@ -1,7 +1,5 @@
package net.filebot.ui.subtitle;
import static javax.swing.BorderFactory.*;
import java.awt.Color;
@ -15,7 +13,6 @@ import javax.swing.plaf.basic.ComboPopup;
import net.filebot.ResourceManager;
public class SimpleComboBox extends JComboBox {
public SimpleComboBox() {
@ -23,7 +20,6 @@ public class SimpleComboBox extends JComboBox {
setBorder(createEmptyBorder());
}
private static class SimpleComboBoxUI extends BasicComboBoxUI {
@Override
@ -37,7 +33,6 @@ public class SimpleComboBox extends JComboBox {
return button;
}
@Override
protected ComboPopup createPopup() {
return new BasicComboPopup(comboBox) {
@ -52,13 +47,13 @@ public class SimpleComboBox extends JComboBox {
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)));

View File

@ -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));
}

View File

@ -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,7 +62,6 @@ 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>();
@ -73,7 +72,6 @@ class SubtitleDownloadComponent extends JComponent {
private JTextField filterEditor = new JTextField();
public SubtitleDownloadComponent() {
final JList packageList = new JList(createPackageListModel());
packageList.setFixedCellHeight(32);
@ -96,7 +94,6 @@ class SubtitleDownloadComponent extends JComponent {
return file.getName();
}
@Override
protected Icon convertValueToIcon(Object value) {
if (SUBTITLE_FILES.accept(value.toString()))
@ -151,7 +148,6 @@ class SubtitleDownloadComponent extends JComponent {
});
}
protected ListModel createPackageListModel() {
// allow filtering by language name and subtitle name
MatcherEditor<SubtitlePackage> matcherEditor = new TextComponentMatcherEditor<SubtitlePackage>(filterEditor, new TextFilterator<SubtitlePackage>() {
@ -176,7 +172,6 @@ class SubtitleDownloadComponent extends JComponent {
return new EventListModel<SubtitlePackage>(source);
}
protected ListModel createFileListModel() {
// source list
EventList<MemoryFile> source = getFileModel();
@ -194,7 +189,6 @@ class SubtitleDownloadComponent extends JComponent {
return new EventListModel<MemoryFile>(source);
}
public void reset() {
// cancel and reset download workers
for (SubtitlePackage subtitle : packages) {
@ -204,29 +198,24 @@ class SubtitleDownloadComponent extends JComponent {
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
@ -262,7 +251,6 @@ class SubtitleDownloadComponent extends JComponent {
subtitle.getDownload().start();
}
private void open(Object[] selection) {
try {
for (Object object : selection) {
@ -278,7 +266,6 @@ class SubtitleDownloadComponent extends JComponent {
}
}
private void open(MemoryFile file) throws IOException {
SubtitleViewer viewer = new SubtitleViewer(file.getName());
viewer.getTitleLabel().setText("Subtitle Viewer");
@ -288,79 +275,61 @@ class SubtitleDownloadComponent extends JComponent {
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();
File outputFolder = showOpenDialogSelectFolder(null, "Save Subtitles", this, Settings.isSandboxed());
if (outputFolder != null) {
for (Object object : selection) {
MemoryFile file = (MemoryFile) object;
File destination = new File(folder, validateFileName(file.getName()));
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];
File selectedOutputFolder = null;
SubtitleFileChooser sf = new SubtitleFileChooser();
// default values
SubtitleFormat selectedFormat = SubtitleFormat.SubRip;
long selectedTimingOffset = 0;
Charset selectedEncoding = Charset.forName("UTF-8");
// 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());
}
// 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();
// 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();
}
}
if (selectedOutputFolder != null) {
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);
File destination = new File(selectedOutputFolder, name + "." + selectedFormat.getFilter().extension());
SubtitleFormat targetFormat = sf.getSelectedFormat().getFilter().accept(file.getName()) ? null : sf.getSelectedFormat();
writeFile(exportSubtitles(file, targetFormat, sf.getTimingOffset(), sf.getSelectedEncoding()), destination);
SubtitleFormat targetFormat = selectedFormat.getFilter().accept(file.getName()) ? null : selectedFormat; // check if format conversion is necessary
writeFile(exportSubtitles(file, targetFormat, selectedTimingOffset, selectedEncoding), destination);
}
}
}
} catch (IOException e) {
} catch (Exception e) {
UILogger.log(Level.WARNING, e.getMessage(), e);
}
}
@ -385,19 +354,16 @@ class SubtitleDownloadComponent extends JComponent {
}
}
@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();
@ -430,7 +396,6 @@ class SubtitleDownloadComponent extends JComponent {
}
}
private boolean isPending(Object[] selection) {
for (Object value : selection) {
SubtitlePackage subtitle = (SubtitlePackage) value;
@ -458,19 +423,16 @@ class SubtitleDownloadComponent extends JComponent {
}
}
@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();
@ -488,7 +450,7 @@ class SubtitleDownloadComponent extends JComponent {
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) {

View File

@ -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));
}
}
}

View File

@ -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,17 +227,12 @@ 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());
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;
}
});

View File

@ -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();
}
}

View File

@ -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,51 +10,42 @@ 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");
@ -65,27 +55,24 @@ public class SaveAction extends AbstractAction {
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());
}
}

View File

@ -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();
}
}

View File

@ -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 {

View File

@ -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);