/*
* $Id$
*
* Copyright (c) 2000-2003 by Rodney Kinney
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License (LGPL) as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, copies are available
* at http://www.opensource.org.
*/
package VASSAL.preferences;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.WindowConstants;
import net.miginfocom.swing.MigLayout;
import VASSAL.configure.Configurer;
import VASSAL.i18n.Resources;
import VASSAL.tools.ArchiveWriter;
import VASSAL.tools.SplashScreen;
import VASSAL.tools.WriteErrorDialog;
import VASSAL.tools.io.ZipArchive;
public class PrefsEditor {
private JDialog dialog;
private List<Configurer> options = new ArrayList<Configurer>();
private List<Configurer> extras = new ArrayList<Configurer>();
private boolean iterating = false;
private Map<Configurer,Object> savedValues = new HashMap<Configurer,Object>();
private List<Prefs> prefs = new ArrayList<Prefs>();
private JTabbedPane optionsTab = new JTabbedPane();
private JDialog setupDialog;
private File pfile;
private Action editAction;
public PrefsEditor() {}
public void initDialog(Frame parent) {
if (dialog == null) {
dialog = new JDialog(parent, true);
dialog.setTitle(Resources.getString("Prefs.preferences")); //$NON-NLS-1$
dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
// Handle window closing correctly.
dialog.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
cancel();
}
});
final JButton ok = new JButton(Resources.getString(Resources.OK));
ok.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
save();
}
});
final JButton cancel = new JButton(Resources.getString(Resources.CANCEL));
cancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
cancel();
}
});
dialog.setLayout(new MigLayout("insets dialog"));
dialog.add(optionsTab, "push, grow, wrap unrelated");
dialog.add(ok, "tag ok, split");
dialog.add(cancel, "tag cancel");
}
}
public JDialog getDialog() {
return dialog;
}
public void addPrefs(Prefs p) {
prefs.add(p);
}
public void addOption(String category, Configurer c, String prompt) {
if (prompt != null) {
if (setupDialog == null) {
setupDialog = new JDialog((Frame) null, true);
setupDialog.setTitle(Resources.getString("Prefs.initial_setup")); //$NON-NLS-1$
setupDialog.setLayout(new BoxLayout(setupDialog.getContentPane(), BoxLayout.Y_AXIS));
setupDialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
setupDialog.addComponentListener(new ComponentAdapter() {
public void componentShown(ComponentEvent e) {
SplashScreen.sendAllToBack();
}
});
}
JPanel p = new JPanel();
p.add(new JLabel(prompt));
setupDialog.add(p);
setupDialog.add(c.getControls());
JButton b = new JButton(Resources.getString(Resources.OK));
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
setupDialog.setVisible(false);
}
});
p = new JPanel();
p.add(b);
setupDialog.add(p);
setupDialog.pack();
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
setupDialog.setLocation(
d.width / 2 - setupDialog.getSize().width / 2,
d.height / 2 - setupDialog.getSize().height / 2
);
setupDialog.setVisible(true);
setupDialog.removeAll();
}
addOption(category, c);
}
public synchronized void addOption(String category, Configurer c) {
if (category == null) {
category = Resources.getString("Prefs.general_tab"); //$NON-NLS-1$
}
JPanel pan = null;
int i = optionsTab.indexOfTab(category);
if (i == -1) { // No match
pan = new JPanel();
pan.setLayout(new BoxLayout(pan, BoxLayout.Y_AXIS));
optionsTab.addTab(category, pan);
}
else {
pan = (JPanel) optionsTab.getComponentAt(i);
}
if (iterating) {
extras.add(c);
}
else {
options.add(c);
}
final Box b = Box.createHorizontalBox();
b.add(c.getControls());
b.add(Box.createHorizontalGlue());
pan.add(b);
}
private synchronized void storeValues() {
savedValues.clear();
for (Configurer c : options) {
c.setFrozen(true);
if (c.getValue() != null) {
savedValues.put(c, c.getValue());
}
}
}
protected synchronized void cancel() {
for (Configurer c : options) {
c.setValue(savedValues.get(c));
c.setFrozen(false);
}
dialog.setVisible(false);
}
protected synchronized void save() {
iterating = true;
for (Configurer c : options) {
if ((savedValues.get(c) == null && c.getValue() != null) || (savedValues.get(c) != null && !savedValues.get(c).equals(c.getValue()))) {
c.fireUpdate();
}
c.setFrozen(false);
}
iterating = false;
options.addAll(extras);
extras.clear();
write();
dialog.setVisible(false);
}
public Action getEditAction() {
if (editAction == null) {
editAction = new AbstractAction(
Resources.getString("Prefs.edit_preferences")) { //$NON-NLS-1$
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
storeValues();
dialog.pack();
final Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
dialog.setLocation(d.width / 2 - dialog.getWidth() / 2, 0);
dialog.setVisible(true);
}
};
// FIMXE: setting nmemonic from first letter could cause collisions in
// some languages
editAction.putValue(Action.MNEMONIC_KEY, (int) Resources.getString("Prefs.edit_preferences").charAt(0));
}
return editAction;
}
public void write() {
for (Prefs p : prefs) {
try {
p.save();
}
catch (IOException e) {
WriteErrorDialog.error(e, p.getFile());
}
}
}
public void close() {
write();
}
}