From 3b147b325f2b2bc9dfb28926a9b51ab6b7764742 Mon Sep 17 00:00:00 2001 From: Reinhard Pointner Date: Sun, 2 Aug 2009 11:48:45 +0000 Subject: [PATCH] * added media info button in EpisodeBindingDialog * improved dialog positioning * minor bugfixes * refactoring --- .../format/AssociativeScriptObject.java | 25 +- .../filebot/format/EpisodeBindingBean.java | 4 +- .../filebot/mediainfo/MediaInfo.java | 2 +- .../filebot/ui/AbstractSearchPanel.java | 8 +- .../sourceforge/filebot/ui/SelectDialog.java | 11 +- .../rename/AutoFetchEpisodeListMatcher.java | 2 + .../ui/panel/rename/EpisodeBindingDialog.java | 255 ++++++++++++++---- .../rename/EpisodeBindingDialog.properties | 31 ++- .../ui/panel/rename/EpisodeFormatDialog.java | 3 +- .../filebot/ui/panel/rename/MatchAction.java | 16 +- .../ui/panel/rename/MediaInfoPane.java | 136 ---------- .../filebot/ui/panel/rename/RenamePanel.java | 3 +- .../filebot/ui/panel/sfv/SfvPanel.java | 9 +- .../ui/AbstractFancyListCellRenderer.java | 4 +- .../sourceforge/tuned/ui/ProgressDialog.java | 8 +- .../sourceforge/tuned/ui/TunedUtilities.java | 5 +- 16 files changed, 274 insertions(+), 248 deletions(-) delete mode 100644 source/net/sourceforge/filebot/ui/panel/rename/MediaInfoPane.java diff --git a/source/net/sourceforge/filebot/format/AssociativeScriptObject.java b/source/net/sourceforge/filebot/format/AssociativeScriptObject.java index 8f21f238..68556ee7 100644 --- a/source/net/sourceforge/filebot/format/AssociativeScriptObject.java +++ b/source/net/sourceforge/filebot/format/AssociativeScriptObject.java @@ -18,9 +18,8 @@ public class AssociativeScriptObject implements Scriptable { private final Map properties; - @SuppressWarnings("unchecked") public AssociativeScriptObject(Map properties) { - this.properties = new LenientLookup((Map) properties); + this.properties = new LenientLookup(properties); } @@ -156,15 +155,15 @@ public class AssociativeScriptObject implements Scriptable { * Map allowing look-up of values by a fault-tolerant key as specified by the defining key. * */ - private class LenientLookup extends AbstractMap { + private static class LenientLookup extends AbstractMap { - private final Map> source = new HashMap>(); + private final Map> lookup = new HashMap>(); - public LenientLookup(Map source) { - // populate entry map - for (Entry entry : source.entrySet()) { - this.source.put(definingKey(entry.getKey()), entry); + public LenientLookup(Map source) { + // populate lookup map + for (Entry entry : source.entrySet()) { + lookup.put(definingKey(entry.getKey()), entry); } } @@ -177,13 +176,13 @@ public class AssociativeScriptObject implements Scriptable { @Override public boolean containsKey(Object key) { - return source.containsKey(definingKey(key)); + return lookup.containsKey(definingKey(key)); } @Override public Object get(Object key) { - Entry entry = source.get(definingKey(key)); + Entry entry = lookup.get(definingKey(key)); if (entry != null) return entry.getValue(); @@ -198,13 +197,15 @@ public class AssociativeScriptObject implements Scriptable { @Override public Iterator> iterator() { - return source.values().iterator(); + @SuppressWarnings("unchecked") + Iterator> iterator = (Iterator) lookup.values().iterator(); + return iterator; } @Override public int size() { - return source.size(); + return lookup.size(); } }; } diff --git a/source/net/sourceforge/filebot/format/EpisodeBindingBean.java b/source/net/sourceforge/filebot/format/EpisodeBindingBean.java index b74a0a11..fb5b1f93 100644 --- a/source/net/sourceforge/filebot/format/EpisodeBindingBean.java +++ b/source/net/sourceforge/filebot/format/EpisodeBindingBean.java @@ -211,11 +211,11 @@ public class EpisodeBindingBean { private void checkMediaFile() throws RuntimeException { // make sure file is not null, and that it is an existing file if (mediaFile == null || !mediaFile.isFile()) - throw new RuntimeException(String.format("Illegal media file: %s", mediaFile)); + throw new RuntimeException(String.format("Invalid media file: %s", mediaFile)); } - private MediaInfo getMediaInfo() { + private synchronized MediaInfo getMediaInfo() { if (mediaInfo == null) { // make sure media file is defined checkMediaFile(); diff --git a/source/net/sourceforge/filebot/mediainfo/MediaInfo.java b/source/net/sourceforge/filebot/mediainfo/MediaInfo.java index c566a274..f86639e2 100644 --- a/source/net/sourceforge/filebot/mediainfo/MediaInfo.java +++ b/source/net/sourceforge/filebot/mediainfo/MediaInfo.java @@ -41,7 +41,7 @@ public class MediaInfo implements Closeable { public synchronized boolean open(File file) { - return MediaInfoLibrary.INSTANCE.Open(handle, new WString(file.getAbsolutePath())) > 0; + return file.isFile() && MediaInfoLibrary.INSTANCE.Open(handle, new WString(file.getAbsolutePath())) > 0; } diff --git a/source/net/sourceforge/filebot/ui/AbstractSearchPanel.java b/source/net/sourceforge/filebot/ui/AbstractSearchPanel.java index b2f63782..81886c0a 100644 --- a/source/net/sourceforge/filebot/ui/AbstractSearchPanel.java +++ b/source/net/sourceforge/filebot/ui/AbstractSearchPanel.java @@ -3,6 +3,7 @@ package net.sourceforge.filebot.ui; import static javax.swing.ScrollPaneConstants.*; +import static net.sourceforge.tuned.ui.TunedUtilities.*; import java.awt.Window; import java.awt.event.ActionEvent; @@ -40,7 +41,6 @@ import net.sourceforge.filebot.web.SearchResult; import net.sourceforge.tuned.ExceptionUtilities; import net.sourceforge.tuned.ListChangeSynchronizer; import net.sourceforge.tuned.ui.LabelProvider; -import net.sourceforge.tuned.ui.TunedUtilities; public abstract class AbstractSearchPanel extends JComponent { @@ -97,7 +97,7 @@ public abstract class AbstractSearchPanel extends JComponent { AutoCompleteSupport.install(searchTextField.getEditor(), searchHistory).setFilterMode(TextMatcherEditor.CONTAINS); - TunedUtilities.installAction(this, KeyStroke.getKeyStroke("ENTER"), searchAction); + installAction(this, KeyStroke.getKeyStroke("ENTER"), searchAction); } @@ -383,7 +383,6 @@ public abstract class AbstractSearchPanel extends JComponent { protected SearchResult selectSearchResult(Collection searchResults, Window window) throws Exception { // multiple results have been found, user must select one SelectDialog selectDialog = new SelectDialog(window, searchResults); - configureSelectDialog(selectDialog); selectDialog.setVisible(true); @@ -394,7 +393,8 @@ public abstract class AbstractSearchPanel extends JComponent { protected void configureSelectDialog(SelectDialog selectDialog) { - selectDialog.setIconImage(TunedUtilities.getImage(getIcon())); + selectDialog.setLocation(getOffsetLocation(selectDialog.getOwner())); + selectDialog.setIconImage(getImage(getIcon())); } diff --git a/source/net/sourceforge/filebot/ui/SelectDialog.java b/source/net/sourceforge/filebot/ui/SelectDialog.java index 34a86640..adde7d56 100644 --- a/source/net/sourceforge/filebot/ui/SelectDialog.java +++ b/source/net/sourceforge/filebot/ui/SelectDialog.java @@ -2,6 +2,7 @@ package net.sourceforge.filebot.ui; +import java.awt.Component; import java.awt.Dimension; import java.awt.Window; import java.awt.event.ActionEvent; @@ -48,7 +49,14 @@ public class SelectDialog extends JDialog { list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); list.setSelectedIndex(0); - DefaultFancyListCellRenderer renderer = new DefaultFancyListCellRenderer(4); + DefaultFancyListCellRenderer renderer = new DefaultFancyListCellRenderer(4) { + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + return super.getListCellRendererComponent(list, convertValueToString(value), index, isSelected, cellHasFocus); + } + }; + renderer.setHighlightingEnabled(false); list.setCellRenderer(renderer); @@ -66,7 +74,6 @@ public class SelectDialog extends JDialog { // set default size and location setSize(new Dimension(210, 210)); - setLocation(TunedUtilities.getPreferredLocation(this)); // Shortcut Enter TunedUtilities.installAction(list, KeyStroke.getKeyStroke("released ENTER"), selectAction); diff --git a/source/net/sourceforge/filebot/ui/panel/rename/AutoFetchEpisodeListMatcher.java b/source/net/sourceforge/filebot/ui/panel/rename/AutoFetchEpisodeListMatcher.java index 9e001fae..5a052055 100644 --- a/source/net/sourceforge/filebot/ui/panel/rename/AutoFetchEpisodeListMatcher.java +++ b/source/net/sourceforge/filebot/ui/panel/rename/AutoFetchEpisodeListMatcher.java @@ -3,6 +3,7 @@ package net.sourceforge.filebot.ui.panel.rename; import static net.sourceforge.filebot.FileBotUtilities.*; +import static net.sourceforge.tuned.ui.TunedUtilities.*; import java.io.File; import java.io.FileFilter; @@ -109,6 +110,7 @@ class AutoFetchEpisodeListMatcher extends SwingWorker> selectDialog.getCancelAction().putValue(Action.NAME, "Ignore"); // show dialog + selectDialog.setLocation(getOffsetLocation(selectDialog.getOwner())); selectDialog.setVisible(true); // selected value or null if the dialog was canceled by the user diff --git a/source/net/sourceforge/filebot/ui/panel/rename/EpisodeBindingDialog.java b/source/net/sourceforge/filebot/ui/panel/rename/EpisodeBindingDialog.java index a3f5bced..27797599 100644 --- a/source/net/sourceforge/filebot/ui/panel/rename/EpisodeBindingDialog.java +++ b/source/net/sourceforge/filebot/ui/panel/rename/EpisodeBindingDialog.java @@ -14,8 +14,10 @@ import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.ResourceBundle; import java.util.TreeMap; +import java.util.Map.Entry; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; @@ -38,6 +40,7 @@ import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import javax.swing.JTable; import javax.swing.JTextField; +import javax.swing.RowFilter; import javax.swing.SwingWorker; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; @@ -45,12 +48,15 @@ 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.miginfocom.swing.MigLayout; import net.sourceforge.filebot.MediaTypes; import net.sourceforge.filebot.ResourceManager; import net.sourceforge.filebot.format.EpisodeBindingBean; import net.sourceforge.filebot.format.ExpressionFormat; +import net.sourceforge.filebot.mediainfo.MediaInfo; +import net.sourceforge.filebot.mediainfo.MediaInfo.StreamKind; import net.sourceforge.filebot.web.Episode; import net.sourceforge.filebot.web.EpisodeFormat; import net.sourceforge.tuned.DefaultThreadFactory; @@ -76,11 +82,6 @@ class EpisodeBindingDialog extends JDialog { public EpisodeBindingDialog(Window owner) { super(owner, "Episode Bindings", ModalityType.DOCUMENT_MODAL); - // create image button from action - JButton selectFileButton = new JButton(selectFileAction); - selectFileButton.setHideActionText(true); - selectFileButton.setOpaque(false); - JComponent root = (JComponent) getContentPane(); root.setLayout(new MigLayout("nogrid, fill, insets dialog")); @@ -96,7 +97,8 @@ class EpisodeBindingDialog extends JDialog { inputPanel.add(new JLabel("Media File:"), "wrap 2px"); inputPanel.add(mediaFileTextField, "hmin 20px, growx"); - inputPanel.add(selectFileButton, "gap rel, w 26px!, h 24px!, wrap paragraph"); + inputPanel.add(createImageButton(mediaInfoAction), "gap rel, w 26px!, h 24px!"); + inputPanel.add(createImageButton(selectFileAction), "gap rel, w 26px!, h 24px!, wrap paragraph"); inputContainer.add("Episode Bindings", inputPanel); root.add(inputContainer, "growx, wrap paragraph"); @@ -120,9 +122,34 @@ class EpisodeBindingDialog extends JDialog { } }; + // update example bindings on change episodeTextField.getDocument().addDocumentListener(changeListener); mediaFileTextField.getDocument().addDocumentListener(changeListener); + // disabled by default + mediaInfoAction.setEnabled(false); + + // disable media info action if media file is invalid + mediaFileTextField.getDocument().addDocumentListener(new DocumentListener() { + + @Override + public void changedUpdate(DocumentEvent e) { + mediaInfoAction.setEnabled(getMediaFile() != null && getMediaFile().isFile()); + } + + + @Override + public void removeUpdate(DocumentEvent e) { + changedUpdate(e); + } + + + @Override + public void insertUpdate(DocumentEvent e) { + changedUpdate(e); + } + }); + // finish dialog and close window manually addWindowListener(new WindowAdapter() { @@ -134,15 +161,22 @@ class EpisodeBindingDialog extends JDialog { // initialize window properties setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); - setLocation(getPreferredLocation(this)); setSize(420, 520); } + private JButton createImageButton(Action action) { + JButton button = new JButton(action); + button.setHideActionText(true); + button.setOpaque(false); + + return button; + } + + private JTable createBindingTable(TableModel model) { JTable table = new JTable(model); table.setAutoCreateRowSorter(true); - table.setFillsViewportHeight(true); table.setBackground(Color.white); @@ -270,6 +304,87 @@ class EpisodeBindingDialog extends JDialog { } }; + protected final Action mediaInfoAction = new AbstractAction("Info", ResourceManager.getIcon("action.properties")) { + + private Map>> getMediaInfo(File file) { + try { + MediaInfo mediaInfo = new MediaInfo(); + + // read all media info + if (mediaInfo.open(file)) { + try { + return mediaInfo.snapshot(); + } finally { + mediaInfo.close(); + } + } + } catch (LinkageError e) { + Logger.getLogger("ui").log(Level.SEVERE, "Unable to load native library 'mediainfo'", e); + } + + // could not retrieve media info + return null; + } + + + @Override + public void actionPerformed(ActionEvent evt) { + Map>> mediaInfo = getMediaInfo(getMediaFile()); + + // check if we could get some info + if (mediaInfo == null) + return; + + // create table tab for each stream + JTabbedPane tabbedPane = new JTabbedPane(); + + ResourceBundle bundle = ResourceBundle.getBundle(EpisodeBindingDialog.class.getName()); + RowFilter excludeRowFilter = RowFilter.notFilter(RowFilter.regexFilter(bundle.getString("parameter.exclude"))); + + for (StreamKind streamKind : mediaInfo.keySet()) { + for (Map parameters : mediaInfo.get(streamKind)) { + JPanel panel = new JPanel(new MigLayout("fill")); + panel.setOpaque(false); + + JTable table = new JTable(new ParameterTableModel(parameters)); + table.setAutoCreateRowSorter(true); + table.setFillsViewportHeight(true); + table.setBackground(Color.white); + + // set media info exclude filter + TableRowSorter sorter = (TableRowSorter) table.getRowSorter(); + sorter.setRowFilter(excludeRowFilter); + + panel.add(new JScrollPane(table), "grow"); + tabbedPane.addTab(streamKind.toString(), panel); + } + } + + // show media info dialog + final JDialog dialog = new JDialog(getWindow(evt.getSource()), "MediaInfo", ModalityType.DOCUMENT_MODAL); + + Action closeAction = new AbstractAction("OK") { + + @Override + public void actionPerformed(ActionEvent e) { + dialog.setVisible(false); + dialog.dispose(); + } + }; + + JComponent c = (JComponent) dialog.getContentPane(); + c.setLayout(new MigLayout("fill", "[align center]", "[fill][pref!]")); + c.add(tabbedPane, "grow, wrap"); + c.add(new JButton(closeAction), "wmin 80px, hmin 25px"); + + dialog.pack(); + dialog.setLocationRelativeTo(EpisodeBindingDialog.this); + + dialog.setVisible(true); + } + + }; + protected final Action selectFileAction = new AbstractAction("Select File", ResourceManager.getIcon("action.load")) { @Override @@ -287,24 +402,55 @@ class EpisodeBindingDialog extends JDialog { chooser.setMultiSelectionEnabled(false); if (chooser.showOpenDialog(getWindow(evt.getSource())) == JFileChooser.APPROVE_OPTION) { - File selectedFile = chooser.getSelectedFile(); - - if (selectedFile.isFile()) { - try { - // display media info - MediaInfoPane.showMessageDialog(getWindow(evt.getSource()), selectedFile); - } catch (LinkageError e) { - Logger.getLogger("ui").log(Level.SEVERE, "Unable to load native library 'mediainfo'", e); - } - - // update text field - mediaFileTextField.setText(selectedFile.getAbsolutePath()); - } + // update text field + mediaFileTextField.setText(chooser.getSelectedFile().getAbsolutePath()); } } }; + private static class Evaluator extends SwingWorker { + + private final String expression; + private final Object bindingBean; + + + private Evaluator(String expression, Object bindingBean) { + this.expression = expression; + this.bindingBean = bindingBean; + } + + + public String getExpression() { + return expression; + } + + + @Override + protected String doInBackground() throws Exception { + ExpressionFormat format = new ExpressionFormat(expression) { + + @Override + protected Object[] compile(String expression, Compilable engine) throws ScriptException { + // simple expression format, everything as one expression + return new Object[] { engine.compile(expression) }; + } + }; + + // evaluate expression with given bindings + String value = format.format(bindingBean); + + // check for script exceptions + if (format.caughtScriptException() != null) { + throw format.caughtScriptException(); + } + + return value; + } + + } + + private static class BindingTableModel extends AbstractTableModel { private final List model = new ArrayList(); @@ -410,45 +556,52 @@ class EpisodeBindingDialog extends JDialog { } - private static class Evaluator extends SwingWorker { + private static class ParameterTableModel extends AbstractTableModel { - private final String expression; - private final Object bindingBean; + private final List> data; - private Evaluator(String expression, Object bindingBean) { - this.expression = expression; - this.bindingBean = bindingBean; - } - - - public String getExpression() { - return expression; + public ParameterTableModel(Map data) { + this.data = new ArrayList>(data.entrySet()); } @Override - protected String doInBackground() throws Exception { - ExpressionFormat format = new ExpressionFormat(expression) { - - @Override - protected Object[] compile(String expression, Compilable engine) throws ScriptException { - // simple expression format, everything as one expression - return new Object[] { engine.compile(expression) }; - } - }; - - // evaluate expression with given bindings - String value = format.format(bindingBean); - - // check for script exceptions - if (format.caughtScriptException() != null) { - throw format.caughtScriptException(); - } - - return value; + public int getRowCount() { + return data.size(); } + + @Override + public int getColumnCount() { + return 2; + } + + + @Override + public String getColumnName(int column) { + switch (column) { + case 0: + return "Parameter"; + case 1: + return "Value"; + default: + return null; + } + } + + + @Override + public Object getValueAt(int row, int column) { + switch (column) { + case 0: + return data.get(row).getKey(); + case 1: + return data.get(row).getValue(); + default: + return null; + } + } } } diff --git a/source/net/sourceforge/filebot/ui/panel/rename/EpisodeBindingDialog.properties b/source/net/sourceforge/filebot/ui/panel/rename/EpisodeBindingDialog.properties index 0655f6e0..de3a7db2 100644 --- a/source/net/sourceforge/filebot/ui/panel/rename/EpisodeBindingDialog.properties +++ b/source/net/sourceforge/filebot/ui/panel/rename/EpisodeBindingDialog.properties @@ -1,4 +1,7 @@ -# expressions are tagged so they can be sorted alphabetically +# exclude pattern for media info dialog +parameter.exclude: ^StreamKind|Count$ + +# preview expressions (keys are tagged so they can be sorted alphabetically) # episode expressions expr[a1]: n @@ -22,22 +25,22 @@ expr[c4]: crc32 # media info expressions [media] expr[d1]: media.title -expr[d2]: media.DurationString -expr[d3]: media.OverallBitRateString +expr[d2]: media.durationString +expr[d3]: media.overallBitRateString # media info expressions [video] -expr[e1]: video.Codec -expr[e2]: video.FrameRate -expr[e3]: video.DisplayAspectRatioString -expr[e4]: video.Height -expr[e5]: video.InterlacementString +expr[e1]: video.codec +expr[e2]: video.frameRate +expr[e3]: video.displayAspectRatioString +expr[e4]: video.height +expr[e5]: video.interlacementString # media info expressions [audio] -expr[f1]: audio.Codec -expr[f2]: audio.Channels -expr[f3]: audio.BitRateString -expr[f4]: audio.Language +expr[f1]: audio.codec +expr[f2]: audio.channels +expr[f3]: audio.bitRateString +expr[f4]: audio.language # media info expressions [text] -expr[g1]: text.CodecInfo -expr[g2]: text.Language +expr[g1]: text.codecInfo +expr[g2]: text.language diff --git a/source/net/sourceforge/filebot/ui/panel/rename/EpisodeFormatDialog.java b/source/net/sourceforge/filebot/ui/panel/rename/EpisodeFormatDialog.java index fd86ff66..2f1fb2d7 100644 --- a/source/net/sourceforge/filebot/ui/panel/rename/EpisodeFormatDialog.java +++ b/source/net/sourceforge/filebot/ui/panel/rename/EpisodeFormatDialog.java @@ -7,6 +7,7 @@ import static javax.swing.BorderFactory.*; import static net.sourceforge.tuned.ui.TunedUtilities.*; import java.awt.Color; +import java.awt.Component; import java.awt.Font; import java.awt.Window; import java.awt.event.ActionEvent; @@ -194,7 +195,6 @@ class EpisodeFormatDialog extends JDialog { // initialize window properties setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); - setLocation(getPreferredLocation(this)); pack(); } @@ -423,6 +423,7 @@ class EpisodeFormatDialog extends JDialog { dialog.setMediaFile(sample.getMediaFile()); // open dialog + dialog.setLocationRelativeTo((Component) evt.getSource()); dialog.setVisible(true); if (dialog.getSelectedOption() == EpisodeBindingDialog.Option.APPROVE) { diff --git a/source/net/sourceforge/filebot/ui/panel/rename/MatchAction.java b/source/net/sourceforge/filebot/ui/panel/rename/MatchAction.java index bfd326af..7051ba71 100644 --- a/source/net/sourceforge/filebot/ui/panel/rename/MatchAction.java +++ b/source/net/sourceforge/filebot/ui/panel/rename/MatchAction.java @@ -2,6 +2,8 @@ package net.sourceforge.filebot.ui.panel.rename; +import static net.sourceforge.tuned.ui.TunedUtilities.*; + import java.awt.Cursor; import java.awt.Window; import java.awt.event.ActionEvent; @@ -15,8 +17,6 @@ import java.util.logging.Logger; import javax.swing.AbstractAction; import javax.swing.Icon; -import javax.swing.JComponent; -import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import net.sourceforge.filebot.ResourceManager; @@ -46,9 +46,8 @@ class MatchAction extends AbstractAction { if (model.names().isEmpty() || model.files().isEmpty()) return; - JComponent eventSource = (JComponent) evt.getSource(); - - SwingUtilities.getRoot(eventSource).setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + Window window = getWindow(evt.getSource()); + window.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); BackgroundMatcher backgroundMatcher = new BackgroundMatcher(model, MatchSimilarityMetric.defaultSequence()); backgroundMatcher.execute(); @@ -58,15 +57,16 @@ class MatchAction extends AbstractAction { backgroundMatcher.get(2, TimeUnit.SECONDS); } catch (TimeoutException ex) { // matcher will probably take a while - ProgressDialog progressDialog = createProgressDialog(SwingUtilities.getWindowAncestor(eventSource), backgroundMatcher); + ProgressDialog dialog = createProgressDialog(window, backgroundMatcher); + dialog.setLocation(getOffsetLocation(dialog.getOwner())); // display progress dialog and stop blocking EDT - progressDialog.setVisible(true); + dialog.setVisible(true); } catch (Exception e) { Logger.getLogger(getClass().getName()).log(Level.SEVERE, e.toString(), e); } - SwingUtilities.getRoot(eventSource).setCursor(Cursor.getDefaultCursor()); + window.setCursor(Cursor.getDefaultCursor()); } diff --git a/source/net/sourceforge/filebot/ui/panel/rename/MediaInfoPane.java b/source/net/sourceforge/filebot/ui/panel/rename/MediaInfoPane.java deleted file mode 100644 index 671092aa..00000000 --- a/source/net/sourceforge/filebot/ui/panel/rename/MediaInfoPane.java +++ /dev/null @@ -1,136 +0,0 @@ - -package net.sourceforge.filebot.ui.panel.rename; - - -import static net.sourceforge.tuned.ui.TunedUtilities.*; - -import java.awt.Window; -import java.awt.Dialog.ModalityType; -import java.awt.event.ActionEvent; -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import javax.swing.AbstractAction; -import javax.swing.Action; -import javax.swing.JButton; -import javax.swing.JComponent; -import javax.swing.JDialog; -import javax.swing.JScrollPane; -import javax.swing.JTabbedPane; -import javax.swing.JTable; -import javax.swing.table.AbstractTableModel; - -import net.miginfocom.swing.MigLayout; -import net.sourceforge.filebot.mediainfo.MediaInfo; -import net.sourceforge.filebot.mediainfo.MediaInfo.StreamKind; - - -class MediaInfoPane extends JTabbedPane { - - public MediaInfoPane(File file) { - // get media info - MediaInfo mediaInfo = new MediaInfo(); - - if (!mediaInfo.open(file)) - throw new IllegalArgumentException("Cannot open file: " + file); - - // create tab for each stream - for (Entry>> entry : mediaInfo.snapshot().entrySet()) { - for (Map parameters : entry.getValue()) { - addTableTab(entry.getKey().toString(), parameters); - } - } - - mediaInfo.close(); - } - - - public void addTableTab(String title, Map data) { - JTable table = new JTable(new ParameterTableModel(data)); - table.setFillsViewportHeight(true); - - // allow sorting - table.setAutoCreateRowSorter(true); - - // sort by parameter name - table.getRowSorter().toggleSortOrder(0); - - addTab(title, new JScrollPane(table)); - } - - - public static void showMessageDialog(Window parent, File file) { - final JDialog dialog = new JDialog(parent, "MediaInfo", ModalityType.DOCUMENT_MODAL); - - Action closeAction = new AbstractAction("OK") { - - @Override - public void actionPerformed(ActionEvent e) { - dialog.setVisible(false); - dialog.dispose(); - } - }; - - JComponent c = (JComponent) dialog.getContentPane(); - c.setLayout(new MigLayout("fill", "[align center]", "[fill][pref!]")); - c.add(new MediaInfoPane(file), "grow, wrap"); - c.add(new JButton(closeAction), "wmin 80px, hmin 25px"); - - dialog.setLocation(getPreferredLocation(dialog)); - dialog.pack(); - - dialog.setVisible(true); - } - - - private static class ParameterTableModel extends AbstractTableModel { - - private final List> data; - - - public ParameterTableModel(Map data) { - this.data = new ArrayList>(data.entrySet()); - } - - - @Override - public int getRowCount() { - return data.size(); - } - - - @Override - public int getColumnCount() { - return 2; - } - - - @Override - public String getColumnName(int column) { - switch (column) { - case 0: - return "Parameter"; - case 1: - return "Value"; - } - - return null; - } - - - @Override - public Object getValueAt(int row, int column) { - switch (column) { - case 0: - return data.get(row).getKey(); - case 1: - return data.get(row).getValue(); - } - - return null; - } - } -} diff --git a/source/net/sourceforge/filebot/ui/panel/rename/RenamePanel.java b/source/net/sourceforge/filebot/ui/panel/rename/RenamePanel.java index 26c740e5..592ec727 100644 --- a/source/net/sourceforge/filebot/ui/panel/rename/RenamePanel.java +++ b/source/net/sourceforge/filebot/ui/panel/rename/RenamePanel.java @@ -152,7 +152,7 @@ public class RenamePanel extends JComponent { @Override public void actionPerformed(ActionEvent evt) { EpisodeFormatDialog dialog = new EpisodeFormatDialog(SwingUtilities.getWindowAncestor(RenamePanel.this)); - + dialog.setLocation(getOffsetLocation(dialog.getOwner())); dialog.setVisible(true); switch (dialog.getSelectedOption()) { @@ -191,6 +191,7 @@ public class RenamePanel extends JComponent { History model = HistorySpooler.getInstance().getCompleteHistory(); HistoryDialog dialog = new HistoryDialog(getWindow(RenamePanel.this)); + dialog.setLocationRelativeTo(RenamePanel.this); dialog.setModel(model); // show and block diff --git a/source/net/sourceforge/filebot/ui/panel/sfv/SfvPanel.java b/source/net/sourceforge/filebot/ui/panel/sfv/SfvPanel.java index 22f35190..e8aeb70d 100644 --- a/source/net/sourceforge/filebot/ui/panel/sfv/SfvPanel.java +++ b/source/net/sourceforge/filebot/ui/panel/sfv/SfvPanel.java @@ -48,9 +48,8 @@ public class SfvPanel extends JComponent { private final ChecksumTableTransferablePolicy transferablePolicy = new ChecksumTableTransferablePolicy(table.getModel(), computationService); private final ChecksumTableExportHandler exportHandler = new ChecksumTableExportHandler(table.getModel()); - + public SfvPanel() { - table.setTransferHandler(new DefaultTransferHandler(transferablePolicy, exportHandler)); JPanel contentPane = new JPanel(new MigLayout("insets 0, nogrid, fill", "", "[fill]10px[bottom, pref!]4px")); @@ -128,6 +127,7 @@ public class SfvPanel extends JComponent { } } + private final SaveAction saveAction = new ChecksumTableSaveAction(); private final LoadAction loadAction = new LoadAction(transferablePolicy); @@ -176,7 +176,7 @@ public class SfvPanel extends JComponent { } }; - + protected class ChangeHashTypeAction extends AbstractAction implements PropertyChangeListener { private ChangeHashTypeAction(HashType hash) { @@ -215,7 +215,7 @@ public class SfvPanel extends JComponent { private File selectedColumn = null; - + public ChecksumTableSaveAction() { super(exportHandler); } @@ -282,6 +282,7 @@ public class SfvPanel extends JComponent { }; selectDialog.getHeaderLabel().setText("Select checksum column:"); + selectDialog.setLocationRelativeTo(SfvPanel.this); selectDialog.setVisible(true); this.selectedColumn = selectDialog.getSelectedValue(); diff --git a/source/net/sourceforge/tuned/ui/AbstractFancyListCellRenderer.java b/source/net/sourceforge/tuned/ui/AbstractFancyListCellRenderer.java index cc4086b3..d9e2b31d 100644 --- a/source/net/sourceforge/tuned/ui/AbstractFancyListCellRenderer.java +++ b/source/net/sourceforge/tuned/ui/AbstractFancyListCellRenderer.java @@ -110,10 +110,8 @@ public abstract class AbstractFancyListCellRenderer extends JPanel implements Li @Override - public final Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { configureListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - validate(); return this; diff --git a/source/net/sourceforge/tuned/ui/ProgressDialog.java b/source/net/sourceforge/tuned/ui/ProgressDialog.java index 8481a7a4..e61922ec 100644 --- a/source/net/sourceforge/tuned/ui/ProgressDialog.java +++ b/source/net/sourceforge/tuned/ui/ProgressDialog.java @@ -25,7 +25,7 @@ public class ProgressDialog extends JDialog { private final Cancellable cancellable; - + public ProgressDialog(Window owner, Cancellable cancellable) { super(owner, ModalityType.DOCUMENT_MODAL); @@ -39,7 +39,6 @@ public class ProgressDialog extends JDialog { progressBar.setStringPainted(true); JPanel c = (JPanel) getContentPane(); - c.setLayout(new MigLayout("insets dialog, nogrid, fill")); c.add(iconLabel, "h pref!, w pref!"); @@ -49,8 +48,6 @@ public class ProgressDialog extends JDialog { c.add(new JButton(cancelAction), "align center"); setSize(240, 155); - - setLocation(TunedUtilities.getPreferredLocation(this)); } @@ -81,6 +78,7 @@ public class ProgressDialog extends JDialog { dispose(); } + protected final Action cancelAction = new AbstractAction("Cancel") { @Override @@ -89,7 +87,7 @@ public class ProgressDialog extends JDialog { } }; - + public static interface Cancellable { boolean isCancelled(); diff --git a/source/net/sourceforge/tuned/ui/TunedUtilities.java b/source/net/sourceforge/tuned/ui/TunedUtilities.java index 22c17691..e571c723 100644 --- a/source/net/sourceforge/tuned/ui/TunedUtilities.java +++ b/source/net/sourceforge/tuned/ui/TunedUtilities.java @@ -20,7 +20,6 @@ import javax.swing.Action; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JComponent; -import javax.swing.JDialog; import javax.swing.KeyStroke; import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; @@ -100,9 +99,7 @@ public final class TunedUtilities { } - public static Point getPreferredLocation(JDialog dialog) { - Window owner = dialog.getOwner(); - + public static Point getOffsetLocation(Window owner) { if (owner == null) { Window[] toplevel = Window.getOwnerlessWindows();