package net.pms.newgui; import com.jgoodies.forms.builder.PanelBuilder; import com.jgoodies.forms.layout.CellConstraints; import com.jgoodies.forms.layout.FormLayout; import com.jgoodies.forms.layout.RowSpec; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; import java.util.List; import java.util.Map; import javax.swing.*; import javax.swing.border.EmptyBorder; import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.plaf.metal.MetalIconFactory; import net.pms.Messages; import net.pms.configuration.DeviceConfiguration; import net.pms.configuration.RendererConfiguration; import net.pms.newgui.components.CustomJButton; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.WordUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class RendererPanel extends JPanel { private static final long serialVersionUID = 5130146620433713605L; private static final Logger LOGGER = LoggerFactory.getLogger(RendererPanel.class); private RendererConfiguration renderer; private CellConstraints cc = new CellConstraints(); private static RowSpec rspec = RowSpec.decode("center:pref"); private JPanel editBar; private boolean ready = false; public RendererPanel(final RendererConfiguration renderer) { this.renderer = renderer; } public JPanel buildPanel() { FormLayout layout = new FormLayout("left:pref, 400:grow"); PanelBuilder builder = new PanelBuilder(layout); builder.border(new EmptyBorder(10, 10, 10, 10)); int y = 0; builder.appendRow(rspec); editBar = new JPanel(); editBar.setLayout(new BoxLayout(editBar, BoxLayout.X_AXIS)); builder.add(editBar, cc.xyw(1, ++y, 2)); if (/*renderer.loaded &&*/ !renderer.isFileless()) { buildEditBar(false); } builder.appendRow(rspec); builder.addLabel(" ", cc.xy(1, ++y)); y = addMap(renderer.getDetails(), builder, y); if (renderer.isUpnp()) { y = addStrings("Services", WordUtils.wrap(StringUtils.join(renderer.getUpnpServices(), ", "), 60).split("\n"), builder, y); } if (renderer.isControllable()) { builder.appendRow(rspec); builder.addLabel(" ", cc.xy(1, ++y)); builder.appendRow(rspec); builder.addSeparator(Messages.getString("RendererPanel.1"), cc.xyw(1, ++y, 2)); builder.appendRow(rspec); builder.add(new PlayerControlPanel(renderer.getPlayer()), cc.xyw(1, ++y, 2)); } return builder.getPanel(); } public void buildEditBar(boolean updateUI) { boolean customized = ((DeviceConfiguration) renderer).isCustomized(); boolean repack = ready && editBar.getComponentCount() == 0; editBar.removeAll(); editBar.add(customized ? referenceButton() : editButton(true)); if (renderer.getFile() != null) { editBar.add(Box.createHorizontalGlue()); editBar.add(customized ? editButton(false) : customizeButton()); } if (repack) { SwingUtilities.getWindowAncestor(this).pack(); } else if (updateUI) { editBar.updateUI(); } } public JButton customizeButton() { final CustomJButton open = new CustomJButton("+", MetalIconFactory.getTreeLeafIcon()); open.setHorizontalTextPosition(JButton.CENTER); open.setForeground(Color.lightGray); open.setToolTipText(Messages.getString("RendererPanel.5")); open.setFocusPainted(false); open.addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { DeviceConfiguration d = (DeviceConfiguration) renderer; File f = chooseConf(d.getDeviceDir(), d.getDefaultFilename(d)); if (f != null) { File file = DeviceConfiguration.createDeviceFile(d, f.getName(), true); buildEditBar(true); try { java.awt.Desktop.getDesktop().open(file); } catch (IOException ioe) { LOGGER.debug("Failed to open default desktop application: " + ioe); } } } }); return open; } public JButton referenceButton() { final File ref = ((DeviceConfiguration) renderer).getConfiguration(DeviceConfiguration.RENDERER).getFile(); final CustomJButton open = new CustomJButton(MetalIconFactory.getTreeLeafIcon()); boolean exists = ref != null && ref.exists(); open.setToolTipText(exists ? (Messages.getString("RendererPanel.3") + ": " + ref) : Messages.getString("RendererPanel.4")); open.setFocusPainted(false); open.addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { try { java.awt.Desktop.getDesktop().open(ref); } catch (IOException ioe) { LOGGER.debug("Failed to open default desktop application: " + ioe); } } }); if (!exists) { open.setText("!"); open.setHorizontalTextPosition(JButton.CENTER); open.setForeground(Color.lightGray); open.setEnabled(false); } return open; } public JButton editButton(final boolean create) { final File file = create ? renderer.getUsableFile() : renderer.getFile(); final CustomJButton open = new CustomJButton(((file != null && file.exists() || !create) ? "<html>" : "<html><font color=blue>" + Messages.getString("RendererPanel.2") + ":</font> ") + file.getName() + "</html>", MetalIconFactory.getTreeLeafIcon()); open.setToolTipText(file.getAbsolutePath()); open.setFocusPainted(false); open.addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent e) { boolean exists = file.isFile() && file.exists(); File f = file; if (!exists && create) { f = chooseConf(file.getParentFile(), file.getName()); if (f != null) { File ref = chooseReferenceConf(); if (ref != null) { renderer.createNewFile(renderer, f, true, ref); open.setText(f.getName()); exists = true; } } } if (exists) { try { java.awt.Desktop.getDesktop().open(f); } catch (IOException ioe) { LOGGER.debug("Failed to open default desktop application: " + ioe); } } else { // Conf no longer exists, repair the edit bar buildEditBar(true); } } }); return open; } public File chooseConf(final File dir, final String filename) { final File file = new File(filename); JFileChooser fc = new JFileChooser(dir) { private static final long serialVersionUID = -3606991702534289691L; @Override public boolean isTraversable(File d) { return dir.equals(d); // Disable navigation } @Override public void approveSelection() { if (getSelectedFile().exists()) { switch (JOptionPane.showConfirmDialog(this, Messages.getString("RendererPanel.6"), Messages.getString("RendererPanel.7"), JOptionPane.YES_NO_CANCEL_OPTION)) { case JOptionPane.CANCEL_OPTION: case JOptionPane.NO_OPTION: setSelectedFile(file); case JOptionPane.CLOSED_OPTION: return; } } super.approveSelection(); } }; fc.setAcceptAllFileFilterUsed(false); FileNameExtensionFilter filter = new FileNameExtensionFilter("Conf Files", "conf"); fc.addChoosableFileFilter(filter); fc.setAcceptAllFileFilterUsed(false); // Current dir must be set explicitly before setting selected file (despite constructor call above) fc.setCurrentDirectory(dir); fc.setSelectedFile(file); fc.setFileSelectionMode(JFileChooser.FILES_ONLY); fc.setDialogTitle(Messages.getString("RendererPanel.8")); if (fc.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) { return fc.getSelectedFile(); } return null; } public File chooseReferenceConf() { JFileChooser fc = new JFileChooser(RendererConfiguration.getRenderersDir()); fc.setAcceptAllFileFilterUsed(false); FileNameExtensionFilter filter = new FileNameExtensionFilter("Conf Files", "conf"); fc.addChoosableFileFilter(filter); fc.setAcceptAllFileFilterUsed(true); File defaultRef = new File(RendererConfiguration.getRenderersDir(), "DefaultRenderer.conf"); if (defaultRef.exists()) { fc.setSelectedFile(defaultRef); } fc.setFileSelectionMode(JFileChooser.FILES_ONLY); switch (fc.showDialog(this, Messages.getString("RendererPanel.9"))) { case JFileChooser.APPROVE_OPTION: return fc.getSelectedFile(); case JFileChooser.CANCEL_OPTION: return RendererConfiguration.NOFILE; } return null; } public int addItem(String key, String value, PanelBuilder builder, int y) { builder.appendRow(rspec); builder.addLabel(key.length() > 0 ? key + ": " : "", cc.xy(1, ++y)); JTextField val = new JTextField(value); val.setEditable(false); val.setBackground(Color.white); builder.add(val, cc.xy(2, y)); return y; } public int addMap(Map<String, String> map, PanelBuilder builder, int y) { for (Map.Entry<String, String> entry : map.entrySet()) { y = addItem(entry.getKey(), entry.getValue(), builder, y); } return y; } public int addStrings(String title, String[] strings, PanelBuilder builder, int y) { for (String string : strings) { y = addItem(title, string, builder, y); title = ""; } return y; } public int addList(String title, List<String> list, PanelBuilder builder, int y) { for (String item : list) { y = addItem(title, item, builder, y); title = ""; } return y; } public void update() { removeAll(); add(buildPanel()); JFrame top = (JFrame) SwingUtilities.getWindowAncestor(this); if (top != null) { top.setTitle(renderer.getRendererName() + (renderer.isOffline() ? " [offline]" : "")); top.pack(); } ready = true; } }