* update bindings sample dialog

This commit is contained in:
Reinhard Pointner 2013-12-23 05:35:24 +00:00
parent e6331f1116
commit a2a897843b
3 changed files with 154 additions and 184 deletions

View File

@ -1,7 +1,5 @@
package net.sourceforge.filebot.ui.rename; package net.sourceforge.filebot.ui.rename;
import static net.sourceforge.filebot.MediaTypes.*; import static net.sourceforge.filebot.MediaTypes.*;
import static net.sourceforge.filebot.Settings.*; import static net.sourceforge.filebot.Settings.*;
import static net.sourceforge.filebot.ui.NotificationLogging.*; import static net.sourceforge.filebot.ui.NotificationLogging.*;
@ -66,131 +64,130 @@ import net.sourceforge.filebot.mediainfo.MediaInfoException;
import net.sourceforge.tuned.DefaultThreadFactory; import net.sourceforge.tuned.DefaultThreadFactory;
import net.sourceforge.tuned.ui.LazyDocumentListener; import net.sourceforge.tuned.ui.LazyDocumentListener;
class BindingDialog extends JDialog { class BindingDialog extends JDialog {
private final JTextField infoTextField = new JTextField(); private final JTextField infoTextField = new JTextField();
private final JTextField mediaFileTextField = new JTextField(); private final JTextField mediaFileTextField = new JTextField();
private final Format infoObjectFormat; private final Format infoObjectFormat;
private final BindingTableModel bindingModel = new BindingTableModel(); private final BindingTableModel bindingModel = new BindingTableModel();
private boolean submit = false; private boolean submit = false;
public BindingDialog(Window owner, String title, Format infoObjectFormat, boolean editable) {
public BindingDialog(Window owner, String title, Format infoObjectFormat) {
super(owner, title, ModalityType.DOCUMENT_MODAL); super(owner, title, ModalityType.DOCUMENT_MODAL);
this.infoObjectFormat = infoObjectFormat; this.infoObjectFormat = infoObjectFormat;
JComponent root = (JComponent) getContentPane(); JComponent root = (JComponent) getContentPane();
root.setLayout(new MigLayout("nogrid, fill, insets dialog")); root.setLayout(new MigLayout("nogrid, fill, insets dialog"));
// decorative tabbed pane // decorative tabbed pane
JTabbedPane inputContainer = new JTabbedPane(); JTabbedPane inputContainer = new JTabbedPane();
inputContainer.setFocusable(false); inputContainer.setFocusable(false);
JPanel inputPanel = new JPanel(new MigLayout("nogrid, fill")); JPanel inputPanel = new JPanel(new MigLayout("nogrid, fill"));
inputPanel.setOpaque(false); inputPanel.setOpaque(false);
inputPanel.add(new JLabel("Name:"), "wrap 2px"); inputPanel.add(new JLabel("Name:"), "wrap 2px");
inputPanel.add(infoTextField, "hmin 20px, growx, wrap paragraph"); inputPanel.add(infoTextField, "hmin 20px, growx, wrap paragraph");
inputPanel.add(new JLabel("Media File:"), "wrap 2px"); inputPanel.add(new JLabel("Media File:"), "wrap 2px");
inputPanel.add(mediaFileTextField, "hmin 20px, growx"); inputPanel.add(mediaFileTextField, "hmin 20px, growx");
inputPanel.add(createImageButton(mediaInfoAction), "gap rel, w 26px!, h 24px!"); inputPanel.add(createImageButton(mediaInfoAction), "gap rel, w 26px!, h 24px!");
inputPanel.add(createImageButton(selectFileAction), "gap rel, w 26px!, h 24px!, wrap paragraph"); inputPanel.add(createImageButton(selectFileAction), "gap rel, w 26px!, h 24px!, wrap paragraph");
inputContainer.add("Bindings", inputPanel); inputContainer.add("Bindings", inputPanel);
root.add(inputContainer, "growx, wrap paragraph"); root.add(inputContainer, "growx, wrap paragraph");
root.add(new JLabel("Preview:"), "gap 5px, wrap 2px"); root.add(new JLabel("Preview:"), "gap 5px, wrap 2px");
root.add(new JScrollPane(createBindingTable(bindingModel)), "growx, wrap paragraph:push"); root.add(new JScrollPane(createBindingTable(bindingModel)), "growx, wrap paragraph:push");
root.add(new JButton(approveAction), "tag apply"); root.add(new JButton(approveAction), "tag apply");
root.add(new JButton(cancelAction), "tag cancel"); root.add(new JButton(cancelAction), "tag cancel");
// update preview on change // update preview on change
DocumentListener changeListener = new LazyDocumentListener(1000) { DocumentListener changeListener = new LazyDocumentListener(1000) {
@Override @Override
public void update(DocumentEvent evt) { public void update(DocumentEvent evt) {
// ignore lazy events that come in after the window has been closed // ignore lazy events that come in after the window has been closed
if (bindingModel.executor.isShutdown()) if (bindingModel.executor.isShutdown())
return; return;
bindingModel.setModel(getSampleExpressions(), new MediaBindingBean(getInfoObject(), getMediaFile(), null)); bindingModel.setModel(getSampleExpressions(), new MediaBindingBean(getInfoObject(), getMediaFile(), null));
} }
}; };
// update example bindings on change // update example bindings on change
infoTextField.getDocument().addDocumentListener(changeListener); infoTextField.getDocument().addDocumentListener(changeListener);
mediaFileTextField.getDocument().addDocumentListener(changeListener); mediaFileTextField.getDocument().addDocumentListener(changeListener);
// disabled by default // disabled by default
infoTextField.setEnabled(false); infoTextField.setEnabled(false);
mediaInfoAction.setEnabled(false); mediaInfoAction.setEnabled(false);
// disable media info action if media file is invalid // disable media info action if media file is invalid
mediaFileTextField.getDocument().addDocumentListener(new DocumentListener() { mediaFileTextField.getDocument().addDocumentListener(new DocumentListener() {
@Override @Override
public void changedUpdate(DocumentEvent e) { public void changedUpdate(DocumentEvent e) {
mediaInfoAction.setEnabled(getMediaFile() != null && getMediaFile().isFile()); mediaInfoAction.setEnabled(getMediaFile() != null && getMediaFile().isFile());
} }
@Override @Override
public void removeUpdate(DocumentEvent e) { public void removeUpdate(DocumentEvent e) {
changedUpdate(e); changedUpdate(e);
} }
@Override @Override
public void insertUpdate(DocumentEvent e) { public void insertUpdate(DocumentEvent e) {
changedUpdate(e); changedUpdate(e);
} }
}); });
// finish dialog and close window manually // finish dialog and close window manually
addWindowListener(new WindowAdapter() { addWindowListener(new WindowAdapter() {
@Override @Override
public void windowClosing(WindowEvent e) { public void windowClosing(WindowEvent e) {
finish(false); finish(false);
} }
}); });
mediaFileTextField.setEditable(editable);
infoTextField.setEditable(editable);
selectFileAction.setEnabled(editable);
// initialize window properties // initialize window properties
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
setSize(420, 520); setSize(420, 520);
} }
private JTable createBindingTable(TableModel model) { private JTable createBindingTable(TableModel model) {
JTable table = new JTable(model); JTable table = new JTable(model);
table.setAutoCreateRowSorter(true); table.setAutoCreateRowSorter(true);
table.setFillsViewportHeight(true); table.setFillsViewportHeight(true);
table.setBackground(Color.white); table.setBackground(Color.white);
table.setDefaultRenderer(Future.class, new DefaultTableCellRenderer() { table.setDefaultRenderer(Future.class, new DefaultTableCellRenderer() {
@Override @Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
super.getTableCellRendererComponent(table, null, isSelected, hasFocus, row, column); super.getTableCellRendererComponent(table, null, isSelected, hasFocus, row, column);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Future<String> future = (Future<String>) value; Future<String> future = (Future<String>) value;
// reset state // reset state
setForeground(isSelected ? table.getSelectionForeground() : table.getForeground()); setForeground(isSelected ? table.getSelectionForeground() : table.getForeground());
try { try {
// try to get result // try to get result
setText(future.get(0, TimeUnit.MILLISECONDS)); setText(future.get(0, TimeUnit.MILLISECONDS));
} catch (TimeoutException e) { } catch (TimeoutException e) {
// not ready yet // not ready yet
setText("Pending …"); setText("Pending …");
// highlight cell // highlight cell
if (!isSelected) { if (!isSelected) {
setForeground(new Color(0x6495ED)); // CornflowerBlue setForeground(new Color(0x6495ED)); // CornflowerBlue
@ -198,68 +195,61 @@ class BindingDialog extends JDialog {
} catch (Exception e) { } catch (Exception e) {
// could not evaluate expression // could not evaluate expression
setText("undefined"); setText("undefined");
// highlight cell // highlight cell
if (!isSelected) { if (!isSelected) {
setForeground(Color.gray); setForeground(Color.gray);
} }
} }
return this; return this;
} }
}); });
return table; return table;
} }
private List<String> getSampleExpressions() { private List<String> getSampleExpressions() {
ResourceBundle bundle = ResourceBundle.getBundle(getClass().getName()); ResourceBundle bundle = ResourceBundle.getBundle(getClass().getName());
return Arrays.asList(bundle.getString("expressions").split(",")); return Arrays.asList(bundle.getString("expressions").split(","));
} }
public boolean submit() { public boolean submit() {
return submit; return submit;
} }
private void finish(boolean submit) { private void finish(boolean submit) {
this.submit = submit; this.submit = submit;
// cancel background evaluators // cancel background evaluators
bindingModel.executor.shutdownNow(); bindingModel.executor.shutdownNow();
setVisible(false); setVisible(false);
dispose(); dispose();
} }
public void setInfoObject(Object info) { public void setInfoObject(Object info) {
infoTextField.putClientProperty("model", info); infoTextField.putClientProperty("model", info);
infoTextField.setText(info == null ? "" : infoObjectFormat.format(info)); infoTextField.setText(info == null ? "" : infoObjectFormat.format(info));
} }
public void setMediaFile(File mediaFile) { public void setMediaFile(File mediaFile) {
mediaFileTextField.setText(mediaFile == null ? "" : mediaFile.getAbsolutePath()); mediaFileTextField.setText(mediaFile == null ? "" : mediaFile.getAbsolutePath());
} }
public Object getInfoObject() { public Object getInfoObject() {
return infoTextField.getClientProperty("model"); return infoTextField.getClientProperty("model");
} }
public File getMediaFile() { public File getMediaFile() {
File file = new File(mediaFileTextField.getText()); File file = new File(mediaFileTextField.getText());
// allow only absolute paths // allow only absolute paths
return file.isAbsolute() ? file : null; return file.isAbsolute() ? file : null;
} }
protected final Action approveAction = new AbstractAction("Use Bindings", ResourceManager.getIcon("dialog.continue")) { protected final Action approveAction = new AbstractAction("Use Bindings", ResourceManager.getIcon("dialog.continue")) {
@Override @Override
public void actionPerformed(ActionEvent evt) { public void actionPerformed(ActionEvent evt) {
// check episode and media file // check episode and media file
@ -275,21 +265,21 @@ class BindingDialog extends JDialog {
} }
} }
}; };
protected final Action cancelAction = new AbstractAction("Cancel", ResourceManager.getIcon("dialog.cancel")) { protected final Action cancelAction = new AbstractAction("Cancel", ResourceManager.getIcon("dialog.cancel")) {
@Override @Override
public void actionPerformed(ActionEvent evt) { public void actionPerformed(ActionEvent evt) {
finish(true); finish(true);
} }
}; };
protected final Action mediaInfoAction = new AbstractAction("Info", ResourceManager.getIcon("action.properties")) { protected final Action mediaInfoAction = new AbstractAction("Info", ResourceManager.getIcon("action.properties")) {
private Map<StreamKind, List<Map<String, String>>> getMediaInfo(File file) { private Map<StreamKind, List<Map<String, String>>> getMediaInfo(File file) {
try { try {
MediaInfo mediaInfo = new MediaInfo(); MediaInfo mediaInfo = new MediaInfo();
// read all media info // read all media info
if (mediaInfo.open(file)) { if (mediaInfo.open(file)) {
try { try {
@ -301,93 +291,92 @@ class BindingDialog extends JDialog {
} catch (MediaInfoException e) { } catch (MediaInfoException e) {
UILogger.log(Level.SEVERE, e.getMessage(), e); UILogger.log(Level.SEVERE, e.getMessage(), e);
} }
// could not retrieve media info // could not retrieve media info
return null; return null;
} }
@Override @Override
public void actionPerformed(ActionEvent evt) { public void actionPerformed(ActionEvent evt) {
Map<StreamKind, List<Map<String, String>>> mediaInfo = getMediaInfo(getMediaFile()); Map<StreamKind, List<Map<String, String>>> mediaInfo = getMediaInfo(getMediaFile());
// check if we could get some info // check if we could get some info
if (mediaInfo == null) if (mediaInfo == null)
return; return;
// create table tab for each stream // create table tab for each stream
JTabbedPane tabbedPane = new JTabbedPane(); JTabbedPane tabbedPane = new JTabbedPane();
ResourceBundle bundle = ResourceBundle.getBundle(BindingDialog.class.getName()); ResourceBundle bundle = ResourceBundle.getBundle(BindingDialog.class.getName());
RowFilter<Object, Object> excludeRowFilter = RowFilter.notFilter(RowFilter.regexFilter(bundle.getString("parameter.exclude"))); RowFilter<Object, Object> excludeRowFilter = RowFilter.notFilter(RowFilter.regexFilter(bundle.getString("parameter.exclude")));
for (StreamKind streamKind : mediaInfo.keySet()) { for (StreamKind streamKind : mediaInfo.keySet()) {
for (Map<String, String> parameters : mediaInfo.get(streamKind)) { for (Map<String, String> parameters : mediaInfo.get(streamKind)) {
JPanel panel = new JPanel(new MigLayout("fill")); JPanel panel = new JPanel(new MigLayout("fill"));
panel.setOpaque(false); panel.setOpaque(false);
JTable table = new JTable(new ParameterTableModel(parameters)); JTable table = new JTable(new ParameterTableModel(parameters));
table.setAutoCreateRowSorter(true); table.setAutoCreateRowSorter(true);
table.setFillsViewportHeight(true); table.setFillsViewportHeight(true);
table.setBackground(Color.white); table.setBackground(Color.white);
// set media info exclude filter // set media info exclude filter
TableRowSorter<?> sorter = (TableRowSorter<?>) table.getRowSorter(); TableRowSorter<?> sorter = (TableRowSorter<?>) table.getRowSorter();
sorter.setRowFilter(excludeRowFilter); sorter.setRowFilter(excludeRowFilter);
panel.add(new JScrollPane(table), "grow"); panel.add(new JScrollPane(table), "grow");
tabbedPane.addTab(streamKind.toString(), panel); tabbedPane.addTab(streamKind.toString(), panel);
} }
} }
// show media info dialog // show media info dialog
final JDialog dialog = new JDialog(getWindow(evt.getSource()), "MediaInfo", ModalityType.DOCUMENT_MODAL); final JDialog dialog = new JDialog(getWindow(evt.getSource()), "MediaInfo", ModalityType.DOCUMENT_MODAL);
Action closeAction = new AbstractAction("OK") { Action closeAction = new AbstractAction("OK") {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
dialog.setVisible(false); dialog.setVisible(false);
dialog.dispose(); dialog.dispose();
} }
}; };
JComponent c = (JComponent) dialog.getContentPane(); JComponent c = (JComponent) dialog.getContentPane();
c.setLayout(new MigLayout("fill", "[align center]", "[fill][pref!]")); c.setLayout(new MigLayout("fill", "[align center]", "[fill][pref!]"));
c.add(tabbedPane, "grow, wrap"); c.add(tabbedPane, "grow, wrap");
c.add(new JButton(closeAction), "wmin 80px, hmin 25px"); c.add(new JButton(closeAction), "wmin 80px, hmin 25px");
dialog.pack(); dialog.pack();
dialog.setLocationRelativeTo(BindingDialog.this); dialog.setLocationRelativeTo(BindingDialog.this);
dialog.setVisible(true); dialog.setVisible(true);
} }
}; };
protected final Action selectFileAction = new AbstractAction("Select File", ResourceManager.getIcon("action.load")) { protected final Action selectFileAction = new AbstractAction("Select File", ResourceManager.getIcon("action.load")) {
@Override @Override
public void actionPerformed(ActionEvent evt) { public void actionPerformed(ActionEvent evt) {
JFileChooser chooser = new JFileChooser(); JFileChooser chooser = new JFileChooser();
chooser.setSelectedFile(getMediaFile()); chooser.setSelectedFile(getMediaFile());
// collect media file extensions (video, audio and subtitle files) // collect media file extensions (video, audio and subtitle files)
List<String> extensions = new ArrayList<String>(); List<String> extensions = new ArrayList<String>();
Collections.addAll(extensions, VIDEO_FILES.extensions()); Collections.addAll(extensions, VIDEO_FILES.extensions());
Collections.addAll(extensions, AUDIO_FILES.extensions()); Collections.addAll(extensions, AUDIO_FILES.extensions());
Collections.addAll(extensions, SUBTITLE_FILES.extensions()); Collections.addAll(extensions, SUBTITLE_FILES.extensions());
chooser.setFileFilter(new FileNameExtensionFilter("Media files", extensions.toArray(new String[0]))); chooser.setFileFilter(new FileNameExtensionFilter("Media files", extensions.toArray(new String[0])));
chooser.setMultiSelectionEnabled(false); chooser.setMultiSelectionEnabled(false);
if (chooser.showOpenDialog(getWindow(evt.getSource())) == JFileChooser.APPROVE_OPTION) { if (chooser.showOpenDialog(getWindow(evt.getSource())) == JFileChooser.APPROVE_OPTION) {
// update text field // update text field
File file = chooser.getSelectedFile(); File file = chooser.getSelectedFile();
// set file // set file
mediaFileTextField.setText(file.getAbsolutePath()); mediaFileTextField.setText(file.getAbsolutePath());
// set info object from xattr if possible // set info object from xattr if possible
if (useExtendedFileAttributes()) { if (useExtendedFileAttributes()) {
try { try {
@ -407,48 +396,43 @@ class BindingDialog extends JDialog {
} }
} }
}; };
private static class Evaluator extends SwingWorker<String, Void> { private static class Evaluator extends SwingWorker<String, Void> {
private final String expression; private final String expression;
private final Object bindingBean; private final Object bindingBean;
private Evaluator(String expression, Object bindingBean) { private Evaluator(String expression, Object bindingBean) {
this.expression = expression; this.expression = expression;
this.bindingBean = bindingBean; this.bindingBean = bindingBean;
} }
public String getExpression() { public String getExpression() {
return expression; return expression;
} }
@Override @Override
protected String doInBackground() throws Exception { protected String doInBackground() throws Exception {
ExpressionFormat format = new ExpressionFormat(expression) { ExpressionFormat format = new ExpressionFormat(expression) {
@Override @Override
protected Object[] compile(String expression) throws ScriptException { protected Object[] compile(String expression) throws ScriptException {
// simple expression format, everything as one expression // simple expression format, everything as one expression
return new Object[] { compileScriptlet(expression) }; return new Object[] { compileScriptlet(expression) };
} }
}; };
// evaluate expression with given bindings // evaluate expression with given bindings
String value = format.format(bindingBean); String value = format.format(bindingBean);
// check for script exceptions // check for script exceptions
if (format.caughtScriptException() != null) { if (format.caughtScriptException() != null) {
throw format.caughtScriptException(); throw format.caughtScriptException();
} }
return value; return value;
} }
@Override @Override
public String toString() { public String toString() {
try { try {
@ -458,159 +442,144 @@ class BindingDialog extends JDialog {
} }
} }
} }
private static class BindingTableModel extends AbstractTableModel { private static class BindingTableModel extends AbstractTableModel {
private final List<Evaluator> model = new ArrayList<Evaluator>(); private final List<Evaluator> model = new ArrayList<Evaluator>();
private final ExecutorService executor = Executors.newFixedThreadPool(2, new DefaultThreadFactory("Evaluator", Thread.MIN_PRIORITY)); private final ExecutorService executor = Executors.newFixedThreadPool(2, new DefaultThreadFactory("Evaluator", Thread.MIN_PRIORITY));
public void setModel(Collection<String> expressions, Object bindingBean) { public void setModel(Collection<String> expressions, Object bindingBean) {
// cancel old workers and clear model // cancel old workers and clear model
clear(); clear();
for (String expression : expressions) { for (String expression : expressions) {
Evaluator evaluator = new Evaluator(expression, bindingBean) { Evaluator evaluator = new Evaluator(expression, bindingBean) {
@Override @Override
protected void done() { protected void done() {
// update cell when computation is complete // update cell when computation is complete
fireTableCellUpdated(this); fireTableCellUpdated(this);
} }
}; };
// enqueue for background execution // enqueue for background execution
executor.execute(evaluator); executor.execute(evaluator);
model.add(evaluator); model.add(evaluator);
} }
// update view // update view
fireTableDataChanged(); fireTableDataChanged();
} }
public void clear() { public void clear() {
for (Evaluator evaluator : model) { for (Evaluator evaluator : model) {
evaluator.cancel(true); evaluator.cancel(true);
} }
model.clear(); model.clear();
// update view // update view
fireTableDataChanged(); fireTableDataChanged();
} }
public void fireTableCellUpdated(Evaluator element) { public void fireTableCellUpdated(Evaluator element) {
int index = model.indexOf(element); int index = model.indexOf(element);
if (index >= 0) { if (index >= 0) {
fireTableCellUpdated(index, 1); fireTableCellUpdated(index, 1);
} }
} }
@Override @Override
public String getColumnName(int column) { public String getColumnName(int column) {
switch (column) { switch (column) {
case 0: case 0:
return "Expression"; return "Expression";
case 1: case 1:
return "Value"; return "Value";
default: default:
return null; return null;
} }
} }
@Override @Override
public int getColumnCount() { public int getColumnCount() {
return 2; return 2;
} }
@Override @Override
public int getRowCount() { public int getRowCount() {
return model.size(); return model.size();
} }
@Override @Override
public Class<?> getColumnClass(int column) { public Class<?> getColumnClass(int column) {
switch (column) { switch (column) {
case 0: case 0:
return String.class; return String.class;
case 1: case 1:
return Future.class; return Future.class;
default: default:
return null; return null;
} }
} }
@Override @Override
public Object getValueAt(int row, int column) { public Object getValueAt(int row, int column) {
switch (column) { switch (column) {
case 0: case 0:
return model.get(row).getExpression(); return model.get(row).getExpression();
case 1: case 1:
return model.get(row); return model.get(row);
default: default:
return null; return null;
} }
} }
} }
private static class ParameterTableModel extends AbstractTableModel { private static class ParameterTableModel extends AbstractTableModel {
private final List<Entry<?, ?>> data; private final List<Entry<?, ?>> data;
public ParameterTableModel(Map<?, ?> data) { public ParameterTableModel(Map<?, ?> data) {
this.data = new ArrayList<Entry<?, ?>>(data.entrySet()); this.data = new ArrayList<Entry<?, ?>>(data.entrySet());
} }
@Override @Override
public int getRowCount() { public int getRowCount() {
return data.size(); return data.size();
} }
@Override @Override
public int getColumnCount() { public int getColumnCount() {
return 2; return 2;
} }
@Override @Override
public String getColumnName(int column) { public String getColumnName(int column) {
switch (column) { switch (column) {
case 0: case 0:
return "Parameter"; return "Parameter";
case 1: case 1:
return "Value"; return "Value";
default: default:
return null; return null;
} }
} }
@Override @Override
public Object getValueAt(int row, int column) { public Object getValueAt(int row, int column) {
switch (column) { switch (column) {
case 0: case 0:
return data.get(row).getKey(); return data.get(row).getKey();
case 1: case 1:
return data.get(row).getValue(); return data.get(row).getValue();
default: default:
return null; return null;
} }
} }
} }
} }

View File

@ -2,4 +2,4 @@
parameter.exclude: ^StreamKind|Count$ parameter.exclude: ^StreamKind|Count$
# preview expressions (keys are tagged so they can be sorted alphabetically) # preview expressions (keys are tagged so they can be sorted alphabetically)
expressions: n,y,s,e,t,d,startdate,absolute,special,imdbid,episode,sxe,s00e00,movie,vc,ac,cf,vf,af,resolution,hpi,ws,sdhd,source,group,crc32,fn,ext,file,pi,pn,lang,actors,director,collection,genres,certification,rating,dim,info.runtime,info.status,imdb.rating,imdb.votes,media.title,media.durationString,media.overallBitRateString,video.codecID,video.frameRate,video.displayAspectRatioString,video.height,video.scanType,audio.format,audio.bitRateString,audio.language,text.codecInfo,text.language expressions: n,y,s,e,es,sxe,s00e00,t,d,startdate,absolute,special,episode,series,primaryTitle,alias,movie,tmdbid,imdbid,music,artist,albumArtist,album,pi,pn,lang,actors,director,collection,genres,certification,rating,vc,ac,cf,vf,hpi,af,resolution,dim,ws,sdhd,source,group,original,fn,ext,file,file.name,folder,folder.name,crc32,info,info.runtime,info.status,imdb,imdb.rating,imdb.votes,duration,seconds,minutes,media,media.title,media.overallBitRateString,video,video.codecID,video.frameRate,video.displayAspectRatioString,video.scanType,audio,audio.bitRateString,audio.language,audios,audios.language,text,text.codecInfo,text.language,texts,texts.language

View File

@ -88,11 +88,12 @@ import com.cedarsoftware.util.io.JsonWriter;
public class FormatDialog extends JDialog { public class FormatDialog extends JDialog {
private boolean submit = false; private boolean submit = false;
private Mode mode;
private ExpressionFormat format; private ExpressionFormat format;
private MediaBindingBean sample; private Mode mode;
private boolean locked = false;
private MediaBindingBean sample = null;
private ExecutorService executor = createExecutor(); private ExecutorService executor = createExecutor();
private RunnableFuture<String> currentPreviewFuture; private RunnableFuture<String> currentPreviewFuture;
@ -233,6 +234,7 @@ public class FormatDialog extends JDialog {
public void setState(Mode mode, MediaBindingBean bindings, boolean locked) { public void setState(Mode mode, MediaBindingBean bindings, boolean locked) {
this.mode = mode; this.mode = mode;
this.locked = locked;
if (locked) { if (locked) {
this.setTitle(String.format("%s Format", mode)); this.setTitle(String.format("%s Format", mode));
@ -245,7 +247,6 @@ public class FormatDialog extends JDialog {
switchEditModeAction.putValue(Action.NAME, String.format("Switch to %s Format", mode.next())); switchEditModeAction.putValue(Action.NAME, String.format("Switch to %s Format", mode.next()));
switchEditModeAction.setEnabled(!locked); switchEditModeAction.setEnabled(!locked);
changeSampleAction.setEnabled(!locked);
updateHelpPanel(mode); updateHelpPanel(mode);
@ -606,7 +607,7 @@ public class FormatDialog extends JDialog {
@Override @Override
public void actionPerformed(ActionEvent evt) { public void actionPerformed(ActionEvent evt) {
BindingDialog dialog = new BindingDialog(getWindow(evt.getSource()), String.format("%s Bindings", mode), mode.getFormat()); BindingDialog dialog = new BindingDialog(getWindow(evt.getSource()), String.format("%s Bindings", mode), mode.getFormat(), !locked);
dialog.setInfoObject(sample.getInfoObject()); dialog.setInfoObject(sample.getInfoObject());
dialog.setMediaFile(sample.getMediaFile()); dialog.setMediaFile(sample.getMediaFile());