/* $Id: SettingsTab.java 124 2008-03-06 07:19:25Z bananeweizen $
* GNU GPL Version 2, Copyright (C) 2005 Paul C. Kunysch */
package de.kunysch.tvbrowser.localimdb;
import de.kunysch.localimdb.ImportGui;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.ListSelectionEvent;
import util.ui.Localizer;
import de.kunysch.tvbrowser.Settings;
import devplugin.Channel;
/**
* A SettingsTab can create a JPanel for the Settings dialog and it can store
* settings when requested.
*/
public class SettingsTab implements devplugin.SettingsTab {
private static Localizer mLocalizer = util.ui.Localizer.getLocalizerFor(SettingsTab.class);
private final Plugin plugin;
private final Settings settings;
private JCheckBox[] channelList = new JCheckBox[0];
private final JCheckBox skipNoYearChk;
private final JCheckBox skipRepeated;
private final JCheckBox skipEpisodes;
private final JCheckBox skipModerated;
private final JSpinner maxYearDeviationSp;
private final JSpinner minVotesSp;
private final JButton downloadBtn;
private final JList ignoreList;
/** The constructor initializes the main controls of all settings panels. */
public SettingsTab(Plugin plugin, Settings settings) {
this.plugin = plugin;
this.settings = settings;
//
skipNoYearChk = new JCheckBox(mLocalizer.msg("opt.noyear", "Skip if 'year' unknown")); //$NON-NLS-1$
skipRepeated = new JCheckBox(mLocalizer.msg("opt.norep", "Skip weekly programs")); //$NON-NLS-1$
skipEpisodes = new JCheckBox(mLocalizer.msg("opt.noeps", "Skip episodes")); //$NON-NLS-1$
skipModerated = new JCheckBox(mLocalizer.msg("opt.nomod", "Skip moderated programs")); //$NON-NLS-1$
maxYearDeviationSp = new JSpinner(new SpinnerNumberModel(0, 0, 3, 1));
minVotesSp = new JSpinner(new SpinnerNumberModel(5, 5, Integer.MAX_VALUE, 5));
downloadBtn = new JButton(mLocalizer.msg("opt.load", "Reload data...")); //$NON-NLS-1$
downloadBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
ImportGui gui = new ImportGui(getParentDialog());
gui.setMovies(SettingsTab.this.plugin.getMovies());
gui.setVisible(true);
}
});
ignoreList = new JList(new IgnoredProgramsModel());
}
/**
* This fills a new JPanel with existing children. The children are updated to
* reflect the current settings.
*/
public JPanel createSettingsPanel() {
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx = c.weighty = 1.0;
c.gridwidth = 1;
c.gridheight = GridBagConstraints.REMAINDER;
panel.add(createChannelAndIgnorePanel(), c);
c.weightx = c.weighty = 0.0;
c.gridheight = 1;
c.gridwidth = GridBagConstraints.REMAINDER;
panel.add(createOptionPanel(), c);
c.weighty = 1.0;
// panel.add(new JPanel(), c);
// c.weighty = 0.0;
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.SOUTH;
panel.add(createViewInfoPanel(), c);
updateControls();
return panel;
}
/**
* A panel with info-buttons is returned.
*/
private JPanel createViewInfoPanel() {
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(0, 2, 7, 7));
final JButton helpBtn = new JButton(mLocalizer.msg("infos.help", "Help...")); //$NON-NLS-1$
final JButton databaseBtn = new JButton(mLocalizer.msg("infos.database", "Database...")); //$NON-NLS-1$
panel.setBorder(BorderFactory.createTitledBorder(mLocalizer.msg("infos", "More information:"))); //$NON-NLS-1$
panel.add(helpBtn);
panel.add(databaseBtn);
helpBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
final JDialog help = new HelpDialog(getParentDialog(), getClass().getResource(
mLocalizer.msg("infos.helpurl", "help/settings.html"))); //$NON-NLS-1$
help.setModal(true);
help.setVisible(true);
}
});
databaseBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Object[] args = { new Integer(plugin.getMovies().getMovieCount()),
new Integer(plugin.getMovies().getTitleCount()), plugin.getMovies().getTimestamp() };
final String message = mLocalizer
.msg(
"infos.database.summary", "<html>{0} movies and {1} titles known.<br>Latest file: {2,date,long}</html>", args); //$NON-NLS-1$
JOptionPane.showMessageDialog(getParentDialog(), message, mLocalizer.msg(
"infos.database.title", "Database info"), JOptionPane.INFORMATION_MESSAGE); //$NON-NLS-1$
}
});
return panel;
}
/** This returns a parent for a component Dialog or null. */
private Dialog getParentDialog() {
Component comp = skipEpisodes;
while (null != comp) {
if (comp instanceof Dialog) {
return (Dialog) comp;
}
comp = comp.getParent();
}
return null;
}
/**
* This internal function updates the controls to reflect the current
* settings.
*/
private void updateControls() {
skipNoYearChk.setSelected(settings.getBoolean(SettingsKeys.REQYEAR));
skipRepeated.setSelected(settings.getBoolean(SettingsKeys.SKIPREP));
skipEpisodes.setSelected(settings.getBoolean(SettingsKeys.SKIPEPS));
skipModerated.setSelected(settings.getBoolean(SettingsKeys.SKIPMOD));
maxYearDeviationSp.setValue(new Integer(settings.getInt(SettingsKeys.YEARDEV)));
minVotesSp.setValue(new Integer(settings.getInt(SettingsKeys.MINVOTES)));
((IgnoredProgramsModel) ignoreList.getModel()).setTitles(settings.getList(SettingsKeys.IGNORETITLES));
}
/** This creates the upper right part of the settings panel. */
private JPanel createOptionPanel() {
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx = 1.0;
c.gridwidth = GridBagConstraints.REMAINDER;
JPanel optionPn = new JPanel(new GridBagLayout());
optionPn.setBorder(BorderFactory.createTitledBorder(mLocalizer.msg("opt", "Options:"))); //$NON-NLS-1$
optionPn.add(skipRepeated, c);
optionPn.add(skipEpisodes, c);
optionPn.add(skipModerated, c);
optionPn.add(skipNoYearChk, c);
c.insets.top = 7;
optionPn.add(new JLabel(mLocalizer.msg("opt.yeardev", "Max. year deviation:")), c); //$NON-NLS-1$
c.insets.top = 0;
c.insets.left = 15;
optionPn.add(maxYearDeviationSp, c);
c.insets.left = 0;
c.insets.top = 7;
optionPn.add(new JLabel(mLocalizer.msg("opt.minvotes", "Minimum votes:")), c); //$NON-NLS-1$
c.insets.top = 0;
c.insets.left = 15;
optionPn.add(minVotesSp, c);
c.insets.left = 0;
c.insets.top = 7;
optionPn.add(downloadBtn, c);
return optionPn;
}
private JComponent createChannelAndIgnorePanel() {
JPanel result = new JPanel(new GridLayout(0, 1));
// result.setLayout(new BoxLayout(result, BoxLayout.Y_AXIS));
result.add(createChannelPanel());
result.add(createIgnorePanel());
// TV-Browser >=2.0 uses PreferredSize as MinimumSize inside a JScrollPane.
Dimension preferred = result.getPreferredSize();
preferred.height = result.getMinimumSize().height;
result.setPreferredSize(preferred);
return result;
}
/** This creates the lower right part of the settings panel. */
/*
* private JPanel createStatsPanel() { GridBagConstraints c = new
* GridBagConstraints(); c.fill = GridBagConstraints.BOTH; c.weightx = 1.0;
* JPanel statsPn = new JPanel(new GridBagLayout());
* statsPn.setBorder(BorderFactory.createTitledBorder(Messages.getString("SettingsTab.stats")));
* //$NON-NLS-1$ final Movies movies = plugin.getMovies(); statsPn.add(new
* JLabel(MessageFormat.format(Messages.getString("SettingsTab.stats.summary"),
* //$NON-NLS-1$ new Object[] { new Integer(movies.getMovieCount()), new
* Integer(movies.getTitleCount()),
* DateFormat.getDateTimeInstance().format(movies.getTimestamp()) })), c);
* return statsPn; }
*/
/** This creates the upper left part of the settings panel. */
private JComponent createChannelPanel() {
JPanel innerChannelPn = new JPanel();
innerChannelPn.setLayout(new BoxLayout(innerChannelPn, BoxLayout.Y_AXIS));
Channel[] subsChannels = devplugin.Plugin.getPluginManager().getSubscribedChannels();
channelList = new JCheckBox[subsChannels.length];
for (int i = 0; i < subsChannels.length; ++i) {
final String name = subsChannels[i].getName();
channelList[i] = new JCheckBox(name);
channelList[i].setSelected(!plugin.isChannelHidden(name));
innerChannelPn.add(channelList[i]);
}
JPanel channelPn = new JPanel(new GridBagLayout());
channelPn.setBorder(BorderFactory.createTitledBorder(mLocalizer.msg("channels", "Filter channels:"))); //$NON-NLS-1$
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx = c.weighty = 1.0;
channelPn.add(new JScrollPane(innerChannelPn, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER), c);
return channelPn;
}
/** This creates the lower left part of the settings panel. */
private JComponent createIgnorePanel() {
JPanel ignorePn = new JPanel(new GridBagLayout());
ignorePn.setBorder(BorderFactory.createTitledBorder(mLocalizer.msg("ignore", "Filter programs:"))); //$NON-NLS-1$
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx = c.weighty = 1.0;
c.gridheight = 1;
c.gridwidth = GridBagConstraints.REMAINDER;
ignorePn.add(new JScrollPane(ignoreList, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED), c);
c.weighty = 0.0;
c.gridheight = GridBagConstraints.REMAINDER;
final JButton removeBtn = new JButton(Localizer.getLocalization(Localizer.I18N_DELETE));
removeBtn.setEnabled(false);
ignorePn.add(removeBtn, c);
ignoreList.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
removeBtn.setEnabled(0 != ignoreList.getSelectedIndices().length);
}
});
removeBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
int[] indices = ignoreList.getSelectedIndices();
for (int i = indices.length - 1; i >= 0; --i) {
((IgnoredProgramsModel) ignoreList.getModel()).remove(indices[i]);
}
}
});
return ignorePn;
}
/** Since TV-Browser 1.1 this icon is used for the settings dialog. */
public Icon getIcon() {
return plugin.getMarkIcon();
}
/** This reads the state from SettingsTab Components and updates our settings. */
public void saveSettings() {
boolean changed = false;
List<String> ignoredChannels = new ArrayList<String>();
for (int i = 0; i < channelList.length; ++i) {
if (!channelList[i].isSelected()) {
ignoredChannels.add(channelList[i].getText());
}
}
changed |= settings.setList(SettingsKeys.HIDE, ignoredChannels.toArray(new String[ignoredChannels.size()]));
changed |= settings.setInt(SettingsKeys.MINVOTES, ((Integer) minVotesSp.getValue()).intValue());
changed |= settings.setInt(SettingsKeys.YEARDEV, ((Integer) maxYearDeviationSp.getValue()).intValue());
changed |= settings.setBoolean(SettingsKeys.REQYEAR, skipNoYearChk.isSelected());
changed |= settings.setBoolean(SettingsKeys.SKIPREP, skipRepeated.isSelected());
changed |= settings.setBoolean(SettingsKeys.SKIPEPS, skipEpisodes.isSelected());
changed |= settings.setBoolean(SettingsKeys.SKIPMOD, skipModerated.isSelected());
changed |= settings.setList(SettingsKeys.IGNORETITLES, ((IgnoredProgramsModel) ignoreList.getModel()).getTitles());
if (changed) {
plugin.fireDayProgramsChanged(devplugin.Plugin.getPluginManager().getCurrentDate());
plugin.fireDayProgramsChanged(devplugin.Plugin.getPluginManager().getCurrentDate().addDays(1));
}
}
/** This returns a name for the SettingsTab. */
public String getTitle() {
return mLocalizer.msg("title", "LocalImdb settings"); //$NON-NLS-1$
}
}