From fa22890573b35421b61c2e690b8fba9d92cce7c2 Mon Sep 17 00:00:00 2001 From: Reinhard Pointner Date: Tue, 24 Mar 2015 11:23:24 +0000 Subject: [PATCH] * allow users to force "Select Folders" and "Select Files" in Rename panel via SHIFT+CLICK "Load" for users that have trouble with file chooser (JavaFX doesn't support Folder & Files file chooser) and especially if Drag-n-Drop doesn't work for some reason --- source/net/filebot/UserFiles.java | 58 +++++++++---------- source/net/filebot/mac/DropToUnlock.java | 3 +- .../net/filebot/ui/analyze/ExtractTool.java | 2 +- .../net/filebot/ui/rename/BindingDialog.java | 2 +- .../net/filebot/ui/rename/FormatDialog.java | 2 +- .../net/filebot/ui/rename/HistoryDialog.java | 2 +- .../rename/NamesListTransferablePolicy.java | 2 +- source/net/filebot/ui/rename/RenameList.java | 26 ++++++++- .../subtitle/SubtitleDownloadComponent.java | 5 +- .../ui/subtitle/SubtitleDropTarget.java | 2 +- .../ui/subtitle/SubtitleUploadDialog.java | 2 +- .../net/filebot/ui/transfer/LoadAction.java | 2 +- .../net/filebot/ui/transfer/SaveAction.java | 2 +- 13 files changed, 66 insertions(+), 44 deletions(-) diff --git a/source/net/filebot/UserFiles.java b/source/net/filebot/UserFiles.java index 73b2cc6d..97fc28f0 100644 --- a/source/net/filebot/UserFiles.java +++ b/source/net/filebot/UserFiles.java @@ -9,6 +9,7 @@ import java.awt.Desktop; import java.awt.Dialog; import java.awt.FileDialog; import java.awt.Frame; +import java.awt.event.ActionEvent; import java.io.File; import java.util.Collection; import java.util.List; @@ -48,25 +49,25 @@ public class UserFiles { defaultFileChooser = fileChooser; } - public static List showLoadDialogSelectFiles(boolean folderMode, boolean multiSelection, File defaultFile, ExtensionFileFilter filter, String title, Object parent) { - String defaultFileKey = (folderMode && filter == null) ? KEY_OPEN_FOLDER : KEY_OPEN_FILE; - List files = defaultFileChooser.showLoadDialogSelectFiles(folderMode, multiSelection, getFileChooserDefaultFile(defaultFileKey, defaultFile), filter, title, parent); + public static List showLoadDialogSelectFiles(boolean folderMode, boolean multiSelection, File defaultFile, ExtensionFileFilter filter, String title, ActionEvent evt) { + String defaultFileKey = ((folderMode && filter == null) || !(folderMode && filter != null && isShiftOrAltDown(evt))) ? KEY_OPEN_FOLDER : KEY_OPEN_FILE; + List files = defaultFileChooser.showLoadDialogSelectFiles(defaultFileKey == KEY_OPEN_FOLDER, multiSelection, getFileChooserDefaultFile(defaultFileKey, defaultFile), filter, title, evt); if (files.size() > 0) { setFileChooserDefaultFile(defaultFileKey, files.get(0)); } return files; } - public static File showSaveDialogSelectFile(boolean folderMode, File defaultFile, String title, Object parent) { - File file = defaultFileChooser.showSaveDialogSelectFile(folderMode, getFileChooserDefaultFile(KEY_SAVE, defaultFile), title, parent); + public static File showSaveDialogSelectFile(boolean folderMode, File defaultFile, String title, ActionEvent evt) { + File file = defaultFileChooser.showSaveDialogSelectFile(folderMode, getFileChooserDefaultFile(KEY_SAVE, defaultFile), title, evt); if (file != null) { setFileChooserDefaultFile(KEY_SAVE, file); } return file; } - public static File showOpenDialogSelectFolder(File defaultFile, String title, Object parent) { - List folder = defaultFileChooser.showLoadDialogSelectFiles(true, false, defaultFile, null, title, parent); + public static File showOpenDialogSelectFolder(File defaultFile, String title, ActionEvent evt) { + List folder = defaultFileChooser.showLoadDialogSelectFiles(true, false, defaultFile, null, title, evt); return folder.size() > 0 ? folder.get(0) : null; } @@ -98,7 +99,7 @@ public class UserFiles { Swing { @Override - public List showLoadDialogSelectFiles(boolean folderMode, boolean multiSelection, File defaultFile, ExtensionFileFilter filter, String title, Object parent) { + public List showLoadDialogSelectFiles(boolean folderMode, boolean multiSelection, File defaultFile, ExtensionFileFilter filter, String title, ActionEvent evt) { JFileChooser chooser = new JFileChooser(); chooser.setDialogTitle(title); chooser.setMultiSelectionEnabled(multiSelection); @@ -116,7 +117,7 @@ public class UserFiles { chooser.setFileFilter(new javax.swing.filechooser.FileNameExtensionFilter(filter.toString(), filter.extensions())); } - if (chooser.showOpenDialog(getWindow(parent)) == JFileChooser.APPROVE_OPTION) { + if (chooser.showOpenDialog(getWindow(evt.getSource())) == JFileChooser.APPROVE_OPTION) { if (chooser.getSelectedFiles().length > 0) return asList(chooser.getSelectedFiles()); if (chooser.getSelectedFile() != null) @@ -126,14 +127,14 @@ public class UserFiles { } @Override - public File showSaveDialogSelectFile(boolean folderMode, File defaultFile, String title, Object parent) { + public File showSaveDialogSelectFile(boolean folderMode, File defaultFile, String title, ActionEvent evt) { JFileChooser chooser = new JFileChooser(); chooser.setDialogTitle(title); chooser.setMultiSelectionEnabled(false); chooser.setFileSelectionMode(folderMode ? JFileChooser.DIRECTORIES_ONLY : JFileChooser.FILES_AND_DIRECTORIES); chooser.setSelectedFile(defaultFile); - if (chooser.showSaveDialog(getWindow(parent)) != JFileChooser.APPROVE_OPTION) { + if (chooser.showSaveDialog(getWindow(evt.getSource())) != JFileChooser.APPROVE_OPTION) { return null; } return chooser.getSelectedFile(); @@ -143,8 +144,8 @@ public class UserFiles { AWT { @Override - public List showLoadDialogSelectFiles(boolean folderMode, boolean multiSelection, File defaultFile, ExtensionFileFilter filter, String title, Object parent) { - FileDialog fileDialog = createFileDialog(parent, title, FileDialog.LOAD, folderMode); + public List showLoadDialogSelectFiles(boolean folderMode, boolean multiSelection, File defaultFile, ExtensionFileFilter filter, String title, ActionEvent evt) { + FileDialog fileDialog = createFileDialog(evt, title, FileDialog.LOAD, folderMode); fileDialog.setTitle(title); fileDialog.setMultipleMode(multiSelection); @@ -166,8 +167,8 @@ public class UserFiles { } @Override - public File showSaveDialogSelectFile(boolean folderMode, File defaultFile, String title, Object parent) { - FileDialog fileDialog = createFileDialog(getWindow(parent), title, FileDialog.SAVE, folderMode); + public File showSaveDialogSelectFile(boolean folderMode, File defaultFile, String title, ActionEvent evt) { + FileDialog fileDialog = createFileDialog(evt, title, FileDialog.SAVE, folderMode); fileDialog.setTitle(title); fileDialog.setMultipleMode(false); if (defaultFile != null) { @@ -182,15 +183,15 @@ public class UserFiles { return files.length > 0 ? files[0] : null; } - public FileDialog createFileDialog(Object parent, String title, int mode, boolean fileDialogForDirectories) { + public FileDialog createFileDialog(ActionEvent evt, String title, int mode, boolean fileDialogForDirectories) { // By default, the AWT File Dialog lets you choose a file. Under certain circumstances, however, it may be proper for you to choose a directory instead. If that is the case, set this property to allow for directory selection in a file dialog. System.setProperty("apple.awt.fileDialogForDirectories", String.valueOf(fileDialogForDirectories)); - if (parent instanceof Frame) { - return new FileDialog((Frame) parent, title, mode); + if (evt.getSource() instanceof Frame) { + return new FileDialog((Frame) evt.getSource(), title, mode); } - if (parent instanceof Dialog) { - return new FileDialog((Dialog) parent, title, mode); + if (evt.getSource() instanceof Dialog) { + return new FileDialog((Dialog) evt.getSource(), title, mode); } Frame[] frames = Frame.getFrames(); @@ -203,7 +204,7 @@ public class UserFiles { private final String KEY_NSOPENPANEL_BROKEN = "NSOPENPANEL_BROKEN"; @Override - public List showLoadDialogSelectFiles(boolean folderMode, boolean multiSelection, File defaultFile, ExtensionFileFilter filter, String title, Object parent) { + public List showLoadDialogSelectFiles(boolean folderMode, boolean multiSelection, File defaultFile, ExtensionFileFilter filter, String title, ActionEvent evt) { // directly use NSOpenPanel for via Objective-C bridge for FILES_AND_DIRECTORIES mode if (folderMode && filter != null) { // NSOpenPanel causes deadlocks on some machines @@ -227,21 +228,20 @@ public class UserFiles { } // default to AWT implementation - return AWT.showLoadDialogSelectFiles(folderMode, multiSelection, defaultFile, filter, title, parent); + return AWT.showLoadDialogSelectFiles(folderMode, multiSelection, defaultFile, filter, title, evt); } @Override - public File showSaveDialogSelectFile(boolean folderMode, File defaultFile, String title, Object parent) { + public File showSaveDialogSelectFile(boolean folderMode, File defaultFile, String title, ActionEvent evt) { // default to AWT implementation - return AWT.showSaveDialogSelectFile(folderMode, defaultFile, title, parent); + return AWT.showSaveDialogSelectFile(folderMode, defaultFile, title, evt); } - }, JavaFX { @Override - public List showLoadDialogSelectFiles(final boolean folderMode, final boolean multiSelection, final File defaultFile, final ExtensionFileFilter filter, final String title, final Object parent) { + public List showLoadDialogSelectFiles(final boolean folderMode, final boolean multiSelection, final File defaultFile, final ExtensionFileFilter filter, final String title, final ActionEvent evt) { return runAndWait(new Callable>() { @Override @@ -294,7 +294,7 @@ public class UserFiles { } @Override - public File showSaveDialogSelectFile(final boolean folderMode, final File defaultFile, final String title, final Object parent) { + public File showSaveDialogSelectFile(final boolean folderMode, final File defaultFile, final String title, final ActionEvent evt) { return runAndWait(new Callable() { @Override @@ -329,9 +329,9 @@ public class UserFiles { } }; - public abstract List showLoadDialogSelectFiles(boolean folderMode, boolean multiSelection, File defaultFile, ExtensionFileFilter filter, String title, Object parent); + public abstract List showLoadDialogSelectFiles(boolean folderMode, boolean multiSelection, File defaultFile, ExtensionFileFilter filter, String title, ActionEvent evt); - public abstract File showSaveDialogSelectFile(boolean folderMode, File defaultFile, String title, Object parent); + public abstract File showSaveDialogSelectFile(boolean folderMode, File defaultFile, String title, ActionEvent evt); } diff --git a/source/net/filebot/mac/DropToUnlock.java b/source/net/filebot/mac/DropToUnlock.java index f44b1b48..cfddbb0e 100644 --- a/source/net/filebot/mac/DropToUnlock.java +++ b/source/net/filebot/mac/DropToUnlock.java @@ -20,6 +20,7 @@ import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Window; import java.awt.datatransfer.Transferable; +import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.geom.RoundRectangle2D; @@ -324,7 +325,7 @@ public class DropToUnlock extends JList { if (index >= 0 && list.getCellBounds(index, index).contains(evt.getPoint())) { File folder = list.getModel().getElementAt(index); if (isLockedFolder(folder)) { - if (null != showOpenDialogSelectFolder(folder, "Grant Permission", getWindow(list))) { + if (null != showOpenDialogSelectFolder(folder, "Grant Permission", new ActionEvent(list, ActionEvent.ACTION_PERFORMED, "Grant"))) { list.updateLockStatus(folder); } } diff --git a/source/net/filebot/ui/analyze/ExtractTool.java b/source/net/filebot/ui/analyze/ExtractTool.java index f7b24a05..c0f15341 100644 --- a/source/net/filebot/ui/analyze/ExtractTool.java +++ b/source/net/filebot/ui/analyze/ExtractTool.java @@ -116,7 +116,7 @@ class ExtractTool extends Tool { if (archives.isEmpty()) return; - File selectedFile = showOpenDialogSelectFolder(archives.get(0).getParentFile(), "Extract to ...", evt.getSource()); + File selectedFile = showOpenDialogSelectFolder(archives.get(0).getParentFile(), "Extract to ...", evt); if (selectedFile == null) return; diff --git a/source/net/filebot/ui/rename/BindingDialog.java b/source/net/filebot/ui/rename/BindingDialog.java index acdf819e..1766e625 100644 --- a/source/net/filebot/ui/rename/BindingDialog.java +++ b/source/net/filebot/ui/rename/BindingDialog.java @@ -355,7 +355,7 @@ class BindingDialog extends JDialog { @Override public void actionPerformed(ActionEvent evt) { ExtensionFileFilter mediaFiles = combineFilter(VIDEO_FILES, AUDIO_FILES, SUBTITLE_FILES); - List file = showLoadDialogSelectFiles(false, false, getMediaFile(), mediaFiles, (String) getValue(NAME), evt.getSource()); + List file = showLoadDialogSelectFiles(false, false, getMediaFile(), mediaFiles, (String) getValue(NAME), evt); if (file.size() > 0) { // update text field diff --git a/source/net/filebot/ui/rename/FormatDialog.java b/source/net/filebot/ui/rename/FormatDialog.java index a3ab80fd..28f7e2ad 100644 --- a/source/net/filebot/ui/rename/FormatDialog.java +++ b/source/net/filebot/ui/rename/FormatDialog.java @@ -682,7 +682,7 @@ public class FormatDialog extends JDialog { } } - File selectedFolder = UserFiles.showOpenDialogSelectFolder(absoluteFolder, "Select Folder", evt.getSource()); + File selectedFolder = UserFiles.showOpenDialogSelectFolder(absoluteFolder, "Select Folder", evt); if (selectedFolder != null) { editor.setText(normalizePathSeparators(selectedFolder.getAbsolutePath()) + "/" + relativeFormat); } diff --git a/source/net/filebot/ui/rename/HistoryDialog.java b/source/net/filebot/ui/rename/HistoryDialog.java index 2c67bfa7..f554d751 100644 --- a/source/net/filebot/ui/rename/HistoryDialog.java +++ b/source/net/filebot/ui/rename/HistoryDialog.java @@ -520,7 +520,7 @@ class HistoryDialog extends JDialog { // change directory option if (selectedOption == Option.ChangeDirectory) { - directory = showOpenDialogSelectFolder(directory, selectedOption.toString(), evt.getSource()); + directory = showOpenDialogSelectFolder(directory, selectedOption.toString(), evt); } } diff --git a/source/net/filebot/ui/rename/NamesListTransferablePolicy.java b/source/net/filebot/ui/rename/NamesListTransferablePolicy.java index 6029bd64..939c9fd9 100644 --- a/source/net/filebot/ui/rename/NamesListTransferablePolicy.java +++ b/source/net/filebot/ui/rename/NamesListTransferablePolicy.java @@ -158,7 +158,7 @@ class NamesListTransferablePolicy extends FileTransferablePolicy { @Override public List getFileFilterExtensions() { - return asList(combineFilter(LIST_FILES, TORRENT_FILES, VERIFICATION_FILES).extensions()); + return asList(combineFilter(VIDEO_FILES, SUBTITLE_FILES, AUDIO_FILES, LIST_FILES, TORRENT_FILES, VERIFICATION_FILES).extensions()); } } diff --git a/source/net/filebot/ui/rename/RenameList.java b/source/net/filebot/ui/rename/RenameList.java index 7064742d..bf542086 100644 --- a/source/net/filebot/ui/rename/RenameList.java +++ b/source/net/filebot/ui/rename/RenameList.java @@ -19,6 +19,7 @@ import net.filebot.ResourceManager; import net.filebot.ui.FileBotList; import net.filebot.ui.transfer.LoadAction; import net.filebot.ui.transfer.TransferablePolicy; +import net.filebot.util.ui.ActionPopup; import net.miginfocom.swing.MigLayout; import ca.odell.glazedlists.EventList; @@ -79,10 +80,9 @@ class RenameList extends FileBotList { getRemoveAction().setEnabled(true); buttonPanel = new JPanel(new MigLayout("insets 1.2mm, nogrid, fill", "align center")); - buttonPanel.add(new JButton(downAction), "gap 10px"); buttonPanel.add(new JButton(upAction), "gap 0"); - buttonPanel.add(new JButton(loadAction), "gap 10px"); + buttonPanel.add(createLoadButton(), "gap 10px"); add(buttonPanel, BorderLayout.SOUTH); @@ -99,6 +99,28 @@ class RenameList extends FileBotList { loadAction.putValue(LoadAction.TRANSFERABLE_POLICY, transferablePolicy); } + private JButton createLoadButton() { + ActionPopup actionPopup = new ActionPopup("Load Files", ResourceManager.getIcon("action.load")); + actionPopup.add(new AbstractAction("Select Folders", ResourceManager.getIcon("tree.closed")) { + + @Override + public void actionPerformed(ActionEvent evt) { + loadAction.actionPerformed(new ActionEvent(evt.getSource(), evt.getID(), evt.getActionCommand(), 0)); + } + }); + actionPopup.add(new AbstractAction("Select Files", ResourceManager.getIcon("file.unknown")) { + + @Override + public void actionPerformed(ActionEvent evt) { + loadAction.actionPerformed(new ActionEvent(evt.getSource(), evt.getID(), evt.getActionCommand(), ActionEvent.SHIFT_MASK)); + } + }); + + JButton b = new JButton(loadAction); + b.setComponentPopupMenu(actionPopup); + return b; + } + private final LoadAction loadAction = new LoadAction(null); private final AbstractAction upAction = new AbstractAction(null, ResourceManager.getIcon("action.up")) { diff --git a/source/net/filebot/ui/subtitle/SubtitleDownloadComponent.java b/source/net/filebot/ui/subtitle/SubtitleDownloadComponent.java index 7a2c9dff..e7214f56 100644 --- a/source/net/filebot/ui/subtitle/SubtitleDownloadComponent.java +++ b/source/net/filebot/ui/subtitle/SubtitleDownloadComponent.java @@ -276,7 +276,7 @@ class SubtitleDownloadComponent extends JComponent { private void save(Object[] selection) { try { // multiple files - File outputFolder = showOpenDialogSelectFolder(null, "Save Subtitles", this); + File outputFolder = showOpenDialogSelectFolder(null, "Save Subtitles", new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "Save")); if (outputFolder != null) { for (Object object : selection) { MemoryFile file = (MemoryFile) object; @@ -290,7 +290,6 @@ class SubtitleDownloadComponent extends JComponent { } private void export(Object[] selection) { - try { File selectedOutputFolder = null; @@ -302,7 +301,7 @@ class SubtitleDownloadComponent extends JComponent { // just use default values when we can't use a JFC with accessory component if (Settings.isMacSandbox()) { // AWT - selectedOutputFolder = showOpenDialogSelectFolder(null, "Export Subtitles", this); + selectedOutputFolder = showOpenDialogSelectFolder(null, "Export Subtitles", new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "Export")); } else { // Swing SubtitleFileChooser sfc = new SubtitleFileChooser(); diff --git a/source/net/filebot/ui/subtitle/SubtitleDropTarget.java b/source/net/filebot/ui/subtitle/SubtitleDropTarget.java index 7e31dd02..144e34d5 100644 --- a/source/net/filebot/ui/subtitle/SubtitleDropTarget.java +++ b/source/net/filebot/ui/subtitle/SubtitleDropTarget.java @@ -130,7 +130,7 @@ abstract class SubtitleDropTarget extends JButton { @Override public void actionPerformed(ActionEvent evt) { // collect media file extensions (video and subtitle files) - List files = showLoadDialogSelectFiles(true, true, null, combineFilter(VIDEO_FILES, SUBTITLE_FILES), "Select Video Folder", evt.getSource()); + List files = showLoadDialogSelectFiles(true, true, null, combineFilter(VIDEO_FILES, SUBTITLE_FILES), "Select Video Folder", evt); if (files.size() > 0) { if (getDropAction(files) != DropAction.Cancel) { diff --git a/source/net/filebot/ui/subtitle/SubtitleUploadDialog.java b/source/net/filebot/ui/subtitle/SubtitleUploadDialog.java index 8a1cfdb5..a1aa991f 100644 --- a/source/net/filebot/ui/subtitle/SubtitleUploadDialog.java +++ b/source/net/filebot/ui/subtitle/SubtitleUploadDialog.java @@ -226,7 +226,7 @@ public class SubtitleUploadDialog extends JDialog { SubtitleMappingTableModel model = (SubtitleMappingTableModel) table.getModel(); SubtitleMapping mapping = model.getData()[table.convertRowIndexToModel(row)]; - List files = showLoadDialogSelectFiles(false, false, mapping.getSubtitle().getParentFile(), VIDEO_FILES, "Select Video File", getWindow(SubtitleUploadDialog.this)); + List files = showLoadDialogSelectFiles(false, false, mapping.getSubtitle().getParentFile(), VIDEO_FILES, "Select Video File", new ActionEvent(table, ActionEvent.ACTION_PERFORMED, "Select")); if (files.size() > 0) { mapping.setVideo(files.get(0)); mapping.setState(SubtitleMapping.Status.CheckPending); diff --git a/source/net/filebot/ui/transfer/LoadAction.java b/source/net/filebot/ui/transfer/LoadAction.java index 6f330e93..d19ae8b5 100644 --- a/source/net/filebot/ui/transfer/LoadAction.java +++ b/source/net/filebot/ui/transfer/LoadAction.java @@ -47,7 +47,7 @@ public class LoadAction extends AbstractAction { return; } - List files = showLoadDialogSelectFiles(true, true, getDefaultFile(), getFileFilter(transferablePolicy), (String) getValue(Action.NAME), evt.getSource()); + List files = showLoadDialogSelectFiles(true, true, getDefaultFile(), getFileFilter(transferablePolicy), (String) getValue(Action.NAME), evt); if (files.isEmpty()) { return; } diff --git a/source/net/filebot/ui/transfer/SaveAction.java b/source/net/filebot/ui/transfer/SaveAction.java index 3bbfce29..6c3627d0 100644 --- a/source/net/filebot/ui/transfer/SaveAction.java +++ b/source/net/filebot/ui/transfer/SaveAction.java @@ -48,7 +48,7 @@ public class SaveAction extends AbstractAction { public void actionPerformed(ActionEvent evt) { try { if (canExport()) { - File file = showSaveDialogSelectFile(false, getDefaultFile(), (String) getValue(Action.NAME), evt.getSource()); + File file = showSaveDialogSelectFile(false, getDefaultFile(), (String) getValue(Action.NAME), evt); if (file != null) { export(file);