Package com.tulskiy.musique.gui.dialogs

Source Code of com.tulskiy.musique.gui.dialogs.ConverterDialog$ConvertTask

/*
* Copyright (c) 2008, 2009, 2010, 2011 Denis Tulskiy
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* version 3 along with this work.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.tulskiy.musique.gui.dialogs;

import com.tulskiy.musique.audio.Converter;
import com.tulskiy.musique.playlist.Track;
import com.tulskiy.musique.system.Application;
import com.tulskiy.musique.system.configuration.Configuration;
import com.tulskiy.musique.util.Util;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.*;
import java.util.List;

/**
* Author: Denis Tulskiy
* Date: Jul 26, 2010
*/
public class ConverterDialog extends JDialog {
    private Application app = Application.getInstance();
    private Configuration config = app.getConfiguration();
    private HashMap<String, JComponent> coders = new LinkedHashMap<String, JComponent>();
    private HashMap<String, String> formatToCoder = new HashMap<String, String>() {{
        put("WAV", "wav");
        put("OGG Vorbis", "ogg");
        put("WavPack", "wv");
        put("Monkey's Audio", "ape");
        put("FLAC", "flac");
    }};

    public ConverterDialog(final JComponent owner, final List<Track> tracks) {
        super(SwingUtilities.windowForComponent(owner), "Convert Files", ModalityType.MODELESS);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        coders.put("WAV", null);
        coders.put("OGG Vorbis", createVorbisSettings());
        coders.put("WavPack", createWavpackSettings());
        coders.put("Monkey's Audio", createAPESettings());
        coders.put("FLAC", null);

        final JComboBox encoder = new JComboBox(coders.keySet().toArray());

        final Box box = Box.createVerticalBox();
        box.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        JPanel format = new JPanel(new BorderLayout());
        format.add(encoder, BorderLayout.CENTER);
        format.setBorder(BorderFactory.createTitledBorder("Format"));
        final JButton coderSettings = new JButton("...");
        final JDialog comp = this;
        coderSettings.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String key = (String) encoder.getSelectedItem();
                showSettingsDialog(key, comp);
            }
        });

        format.add(coderSettings, BorderLayout.EAST);
        encoder.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                String key = (String) e.getItem();
                coderSettings.setEnabled(coders.get(key) != null);
            }
        });
        encoder.setSelectedIndex(-1);
        String codec = config.getString("converter.encoder", "wav");
        for (Map.Entry<String, String> entry : formatToCoder.entrySet()) {
            if (entry.getValue().equals(codec))
                encoder.setSelectedItem(entry.getKey());
        }

        JPanel folder = new JPanel(new GridLayout(2, 2));
        folder.setBorder(BorderFactory.createTitledBorder("Path"));

        final JRadioButton pathSource = new JRadioButton("Source track folder");
        folder.add(pathSource);
        boolean b = config.getBoolean("converter.saveToSourceFolder", true);
        pathSource.setSelected(b);
        JRadioButton pathSpecify = new JRadioButton("Specify folder");
        pathSpecify.setSelected(!b);
        folder.add(pathSpecify);
        ButtonGroup g1 = new ButtonGroup();
        g1.add(pathSource);
        g1.add(pathSpecify);
        folder.add(new JLabel());
        final PathChooser path = new PathChooser(config.getString("converter.path", ""));
        folder.add(path);

        JPanel output = new JPanel(new GridLayout(3, 2));
        output.setBorder(BorderFactory.createTitledBorder("Output files"));
        output.add(new JLabel("When file exists"));
        final JComboBox whenExists = new JComboBox(new String[]{"Ask", "Skip", "Overwrite"});
        whenExists.setSelectedItem(config.getString("converter.actionWhenExists", "Ask"));
        output.add(whenExists);
        output.add(new JLabel("Filename format"));
        final JTextField fileNameFormat = new JTextField();
        fileNameFormat.setText(config.getString("converter.fileNameFormat", "%fileName%"));
        output.add(fileNameFormat);
        final JCheckBox merge = new JCheckBox("Merge files into one image");
        merge.setSelected(config.getBoolean("converter.merge", false));
        output.add(merge);

        box.add(format);
        box.add(folder);
        box.add(output);
        box.add(Box.createVerticalGlue());

        Box buttons = Box.createHorizontalBox();
        buttons.add(Box.createHorizontalGlue());
        JButton ok = new JButton("  OK  ");
        buttons.add(ok);
        ok.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String codec = (String) encoder.getSelectedItem();
                config.setString("converter.encoder", formatToCoder.get(codec));
                config.setBoolean("converter.saveToSourceFolder", pathSource.isSelected());
                config.setString("converter.path", path.getPath());
                config.setString("converter.actionWhenExists", (String) whenExists.getSelectedItem());
                config.setString("converter.fileNameFormat", fileNameFormat.getText());
                config.setBoolean("converter.merge", merge.isSelected());
                setVisible(false);
                dispose();

                ProgressDialog progress = new ProgressDialog(owner, "Converting files");
                progress.show(new ConvertTask(tracks));
            }
        });
        buttons.add(Box.createHorizontalStrut(3));
        JButton cancel = new JButton("Cancel");
        cancel.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                setVisible(false);
                dispose();
            }
        });
        buttons.add(cancel);
        buttons.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        setLayout(new BorderLayout());
        add(box, BorderLayout.NORTH);
        add(buttons, BorderLayout.PAGE_END);
        setSize(500, 400);
        setLocationRelativeTo(SwingUtilities.windowForComponent(owner));
    }

    private void showSettingsDialog(String key, JDialog owner) {
        final JDialog dialog = new JDialog(owner, true);
        dialog.setLayout(new BorderLayout());
        final JComponent comp = coders.get(key);
        setTitle(comp.getName() + " Settings");
        comp.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        dialog.add(comp, BorderLayout.CENTER);

        Box buttons = Box.createHorizontalBox();
        buttons.add(Box.createHorizontalGlue());
        JButton ok = new JButton("  OK  ");
        ok.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                comp.firePropertyChange("accept", 1, 2);
                dialog.setVisible(false);
                dialog.dispose();
            }
        });
        buttons.add(ok);
        buttons.add(Box.createHorizontalStrut(3));
        JButton cancel = new JButton("Cancel");
        cancel.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                dialog.setVisible(false);
                dialog.dispose();
            }
        });
        buttons.add(cancel);
        buttons.add(Box.createHorizontalStrut(10));

        dialog.add(buttons, BorderLayout.PAGE_END);
        dialog.setSize(500, 250);
        dialog.setLocationRelativeTo(owner);
        dialog.setVisible(true);
    }

    private JComponent createWavpackSettings() {
        JPanel panel = new JPanel(new BorderLayout(10, 10));
        panel.setName("WavPack Encoder");
        JPanel misc = new JPanel(new GridLayout(6, 2));
        misc.add(new JLabel("Quality"));
        final JComboBox quality = new JComboBox(new String[]{
                "fast", "normal", "high", "very high"
        });
        quality.setSelectedItem(config.getString("encoder.wavpack.mode", "normal"));
        misc.add(quality);
        final JCheckBox hybrid = new JCheckBox("Enable hybrid mode");
        misc.add(hybrid);
        hybrid.setSelected(config.getBoolean("encoder.wavpack.hybrid.enable", false));
        final JCheckBox maxHybrid = new JCheckBox("Maximum hybrid compression");
        misc.add(maxHybrid);
        maxHybrid.setSelected(config.getBoolean("encoder.wavpack.hybrid.wvc.optimize", false));
        final JCheckBox wvc = new JCheckBox("Create correction file");
        wvc.setSelected(config.getBoolean("encoder.wavpack.hybrid.wvc.enabled", false));
        misc.add(wvc);
        misc.add(new JLabel());
        misc.add(new JLabel("Bitrate, bits/sample"));
        final JSpinner bitrate = new JSpinner(
                new SpinnerNumberModel(4.0, 2.0, 16.0, 0.1));
        bitrate.setValue((double) config.getFloat("encoder.wavpack.hybrid.bitrate", 4f));
        misc.add(bitrate);
        misc.add(new JLabel("Noize shape override"));
        final JSpinner noise = new JSpinner(new SpinnerNumberModel(0, -1.0, 1.0, 0.1));
        noise.setValue((double) config.getFloat("encoder.wavpack.hybrid.noiseShape", 0));
        misc.add(noise);

        ItemListener hybridListener = new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                boolean b = hybrid.isSelected();
                noise.setEnabled(b);
                wvc.setEnabled(b);
                maxHybrid.setEnabled(b);
                bitrate.setEnabled(b);
            }
        };
        hybrid.addItemListener(hybridListener);
        hybridListener.itemStateChanged(null);

        panel.addPropertyChangeListener("accept", new PropertyChangeListener() {
            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                config.setString("encoder.wavpack.mode", (String) quality.getSelectedItem());
                config.setBoolean("encoder.wavpack.hybrid.enable", hybrid.isSelected());
                if (hybrid.isSelected()) {
                    config.setFloat("encoder.wavpack.hybrid.bitrate", ((Number) bitrate.getValue()).floatValue());
                    config.setBoolean("encoder.wavpack.hybrid.wvc.enabled", wvc.isSelected());
                    config.setBoolean("encoder.wavpack.hybrid.wvc.optimize", maxHybrid.isSelected());
                    config.setFloat("encoder.wavpack.hybrid.noiseShape", ((Number) noise.getValue()).floatValue());
                }
            }
        });
        panel.add(misc, BorderLayout.PAGE_START);
        return panel;
    }

    private JComponent createVorbisSettings() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setName("Ogg Vorbis Encoder");
        panel.add(new JLabel("Quality"), BorderLayout.PAGE_START);
        final JSlider slider = new JSlider(-1, 10);
        slider.setMajorTickSpacing(1);
        slider.setPaintLabels(true);
        slider.setPaintTicks(true);
        slider.setSnapToTicks(true);
        slider.setValue((int) (config.getFloat("encoder.vorbis.quality", .3f) * 10));
        Box box = Box.createVerticalBox();
        box.add(slider);
        box.add(Box.createVerticalGlue());
        panel.add(box, BorderLayout.CENTER);

        panel.addPropertyChangeListener("accept", new PropertyChangeListener() {
            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                config.setFloat("encoder.vorbis.quality", slider.getValue() / 10f);
            }
        });
        return panel;
    }

    private JComponent createAPESettings() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setName("Monkey's Audio Encoder");
        panel.add(new JLabel("Compression Level"), BorderLayout.PAGE_START);
        final JSlider slider = new JSlider(1, 5);
        slider.setMajorTickSpacing(1);
        slider.setPaintLabels(true);
        slider.setPaintTicks(true);
        slider.setSnapToTicks(true);
        Hashtable<Integer, JLabel> labels = new Hashtable<Integer, JLabel>();
        labels.put(1, new JLabel("Fast"));
        labels.put(2, new JLabel("Normal"));
        labels.put(3, new JLabel("High"));
        labels.put(4, new JLabel("Extra High"));
        labels.put(5, new JLabel("Insane"));
        slider.setLabelTable(labels);
        slider.setValue(config.getInt("encoder.ape.level", 2000) / 1000);
        Box box = Box.createVerticalBox();
        box.add(slider);
        box.add(Box.createVerticalGlue());
        panel.add(box, BorderLayout.CENTER);

        panel.addPropertyChangeListener("accept", new PropertyChangeListener() {
            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                config.setInt("encoder.ape.level", slider.getValue() * 1000);
            }
        });
        return panel;
    }

    class ConvertTask extends Task {
        Converter converter = new Converter();
        private List<Track> tracks;
        private Formatter formatter;
        private StringBuilder sb;

        ConvertTask(List<Track> tracks) {
            this.tracks = tracks;
            sb = new StringBuilder();
            formatter = new Formatter(sb);
        }

        @Override
        public String getStatus() {
            try {
                Track track = converter.getTrack();
                String status = "Input: ";
                if (track.getTrackData().isFile())
                    status += track.getTrackData().getFile().getAbsolutePath();
                else
                    status += track.getTrackData().getLocation().toString();

                status += "\nOutput: ";
                status += converter.getOutput().getAbsolutePath();
                return status;
            } catch (Exception ignored) {
            }
            return null;
        }

        @Override
        public void abort() {
            converter.stop();
        }

        @Override
        public void start() {
            converter.convert(tracks);
        }

        @Override
        public boolean isIndeterminate() {
            return converter.getTotalSamples() < 0;
        }

        @Override
        public float getProgress() {
            return (float) converter.getCurrentSample() / converter.getTotalSamples();
        }

        @Override
        public String getTitle() {
            String elapsed = Util.formatSeconds(
                    converter.getElapsed() / 1000f, 0);
            String estimated = Util.samplesToTime(
                    (long) converter.getEstimated(),
                    converter.getTrack().getTrackData().getSampleRate(), 0);
            sb.setLength(0);
            formatter.format("Converting. Elapsed: %s Estimated: %s Speed: %.2fx",
                    elapsed, estimated, converter.getSpeed());
            return sb.toString();
        }
    }
}
TOP

Related Classes of com.tulskiy.musique.gui.dialogs.ConverterDialog$ConvertTask

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.