/*
* This file is part of the OSMembrane project.
* More informations under www.osmembrane.de
*
* The project is licensed under the GNU GENERAL PUBLIC LICENSE 3.0.
* for more details about the license see http://www.osmembrane.de/license/
*
* Source: $HeadURL$ ($Revision$)
* Last changed: $Date$
*/
package de.osmembrane.view.dialogs;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Locale;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.filechooser.FileFilter;
import de.osmembrane.model.settings.SettingType;
import de.osmembrane.model.settings.SettingsTypeUpdateInterval;
import de.osmembrane.tools.I18N;
import de.osmembrane.view.AbstractDialog;
import de.osmembrane.view.components.JTextFieldWithButton;
import de.osmembrane.view.interfaces.ISettingsDialog;
/**
* The dialog containing the program's settings
*
* @author tobias_kuhn
*
*/
public class SettingsDialog extends AbstractDialog implements ISettingsDialog {
private static final long serialVersionUID = 6498307196575629577L;
/**
* Whether or not to apply the changes made in the dialog
*/
private boolean applyChanges;
/**
* Components to edit the Osmosis default path
*/
private JTextFieldWithButton osmosisPath;
/**
* Components to edit the JOSM default path
*/
private JTextFieldWithButton josmPath;
/**
* Components to edit the working path
*/
private JTextFieldWithButton workingPath;
/**
* Components to edit the default zoom
*/
private JLabel defaultZoomDisplay;
private JSlider defaultZoom;
/**
* Components to edit the language / locale
*/
private JComboBox language;
private Locale[] locales;
/**
* Components to edit whether short task names shall be used
*/
private JCheckBox shortTasks;
/**
* Components to edit whether default parameters shall be exported
*/
private JCheckBox defaultParamExport;
/**
* Components to edit how much undo steps shall be available
*/
private JSpinner maxUndoSteps;
/**
* Components to edit the grid size
*/
private JLabel rasterSizeDisplay;
private JSlider rasterSize;
private JCheckBox rasterSizeEnable;
/**
* Components to edit whether the startup screen shall be displayed
*/
private JCheckBox showStartup;
/**
* Components to edit how often updates shall be searched
*/
private JComboBox updateInterval;
/**
* Components to edit the PLaF
*/
private JComboBox pLaF;
/**
* Generates a new {@link SettingsDialog}.
*/
public SettingsDialog(Window owner) {
super(owner);
// set the basics up
setLayout(new BorderLayout());
setWindowTitle(I18N.getInstance().getString("View.SettingsDialog"));
// control buttons
JButton okButton = new JButton(I18N.getInstance().getString("View.OK"));
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
applyChanges = true;
hideWindow();
}
});
JButton defaultButton = new JButton(I18N.getInstance().getString(
"View.ResetDefault"));
defaultButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// reset default values
for (SettingType st : SettingType.values()) {
setValue(st, st.getDefaultValue());
}
}
});
JButton cancelButton = new JButton(I18N.getInstance().getString(
"View.Cancel"));
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
applyChanges = false;
hideWindow();
}
});
JPanel buttonCtrlGrid = new JPanel(new GridLayout(1, 3));
buttonCtrlGrid.add(okButton);
buttonCtrlGrid.add(defaultButton);
buttonCtrlGrid.add(cancelButton);
JPanel buttonCtrlFlow = new JPanel(new FlowLayout(FlowLayout.CENTER));
buttonCtrlFlow.add(buttonCtrlGrid);
add(buttonCtrlFlow, BorderLayout.SOUTH);
// actual settings
JPanel settings = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(8, 8, 8, 8);
final int minFieldWidth = 256;
final int minSpinnerWidth = 64;
ActionListener selectFiles = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
final JTextFieldWithButton jtfwb = (JTextFieldWithButton) ((JButton) e
.getSource()).getParent();
JFileChooser fc = new JFileChooser();
fc.setSelectedFile(new File(jtfwb.getValue()));
if (jtfwb.equals(workingPath)) {
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
fc.setAcceptAllFileFilterUsed(false);
}
fc.setFileFilter(new FileFilter() {
@Override
public String getDescription() {
return jtfwb.getToolTipText();
}
@Override
public boolean accept(File f) {
return (jtfwb.equals(workingPath)) ? f.isDirectory()
: f.canExecute();
}
});
if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
jtfwb.setValue(fc.getSelectedFile().getAbsolutePath());
}
}
};
gbc.gridy = 0;
gbc.gridx = 0;
settings.add(
new JLabel(I18N.getInstance().getString(
"Model.Settings.Type.DEFAULT_OSMOSIS_PATH")
+ ":"), gbc);
gbc.gridx = 1;
osmosisPath = new JTextFieldWithButton("", "...");
osmosisPath.setPreferredSize(new Dimension(minFieldWidth, osmosisPath
.getPreferredSize().height));
osmosisPath.setToolTipText(I18N.getInstance().getString(
"Model.Settings.Type.DEFAULT_OSMOSIS_PATH.Description"));
osmosisPath.addButtonActionListener(selectFiles);
settings.add(osmosisPath, gbc);
gbc.gridy = 1;
gbc.gridx = 0;
settings.add(
new JLabel(I18N.getInstance().getString(
"Model.Settings.Type.DEFAULT_JOSM_PATH")
+ ":"), gbc);
gbc.gridx = 1;
josmPath = new JTextFieldWithButton("", "...");
josmPath.setPreferredSize(new Dimension(minFieldWidth, josmPath
.getPreferredSize().height));
josmPath.setToolTipText(I18N.getInstance().getString(
"Model.Settings.Type.DEFAULT_JOSM_PATH.Description"));
josmPath.addButtonActionListener(selectFiles);
settings.add(josmPath, gbc);
gbc.gridy = 2;
gbc.gridx = 0;
settings.add(
new JLabel(I18N.getInstance().getString(
"Model.Settings.Type.DEFAULT_WORKING_DIRECTORY")
+ ":"), gbc);
gbc.gridx = 1;
workingPath = new JTextFieldWithButton("", "...");
workingPath.setPreferredSize(new Dimension(minFieldWidth, workingPath
.getPreferredSize().height));
workingPath.setToolTipText(I18N.getInstance().getString(
"Model.Settings.Type.DEFAULT_WORKING_DIRECTORY.Description"));
workingPath.addButtonActionListener(selectFiles);
settings.add(workingPath, gbc);
gbc.gridy = 3;
gbc.gridx = 0;
settings.add(
new JLabel(I18N.getInstance().getString(
"Model.Settings.Type.ACTIVE_LANGUAGE")
+ ":"), gbc);
gbc.gridx = 1;
language = new JComboBox();
language.setPreferredSize(new Dimension(minFieldWidth, language
.getPreferredSize().height));
language.setToolTipText(I18N.getInstance().getString(
"Model.Settings.Type.ACTIVE_LANGUAGE.Description"));
settings.add(language, gbc);
gbc.gridy = 4;
gbc.gridx = 0;
settings.add(
new JLabel(I18N.getInstance().getString(
"Model.Settings.Type.ACTIVE_PLAF")
+ ":"), gbc);
gbc.gridx = 1;
String[] pLaFOptions = new String[UIManager.getInstalledLookAndFeels().length];
for (int i = 0; i < UIManager.getInstalledLookAndFeels().length; i++) {
pLaFOptions[i] = UIManager.getInstalledLookAndFeels()[i].getName();
}
pLaF = new JComboBox(pLaFOptions);
pLaF.setPreferredSize(new Dimension(minFieldWidth, pLaF
.getPreferredSize().height));
pLaF.setToolTipText(I18N.getInstance().getString(
"Model.Settings.Type.ACTIVE_PLAF.Description"));
settings.add(pLaF, gbc);
gbc.gridy = 5;
gbc.gridx = 0;
settings.add(
new JLabel(I18N.getInstance().getString(
"Model.Settings.Type.UPDATE_INTERVAL")
+ ":"), gbc);
gbc.gridx = 1;
String[] updateOptions = {
I18N.getInstance().getString(
"Model.Settings.Type.UPDATE_INTERVAL.Never"),
I18N.getInstance().getString(
"Model.Settings.Type.UPDATE_INTERVAL.PerDay"),
I18N.getInstance().getString(
"Model.Settings.Type.UPDATE_INTERVAL.PerWeek") };
updateInterval = new JComboBox(updateOptions);
updateInterval.setPreferredSize(new Dimension(minFieldWidth,
updateInterval.getPreferredSize().height));
updateInterval.setToolTipText(I18N.getInstance().getString(
"Model.Settings.Type.UPDATE_INTERVAL.Description"));
settings.add(updateInterval, gbc);
gbc.gridy = 6;
gbc.gridx = 0;
settings.add(
new JLabel(I18N.getInstance().getString(
"Model.Settings.Type.DEFAULT_ZOOM_SIZE")
+ ":"), gbc);
gbc.gridx = 1;
defaultZoomDisplay = new JLabel("");
settings.add(defaultZoomDisplay, gbc);
gbc.gridy = 7;
gbc.gridx = 0;
gbc.gridwidth = 2;
defaultZoom = new JSlider(1, 200);
defaultZoom.setMajorTickSpacing(10);
defaultZoom.setMinorTickSpacing(1);
defaultZoom.setPaintTicks(true);
defaultZoom.setPaintLabels(false);
defaultZoom.setPreferredSize(new Dimension(minFieldWidth, defaultZoom
.getPreferredSize().height));
defaultZoom.setToolTipText(I18N.getInstance().getString(
"Model.Settings.Type.DEFAULT_ZOOM_SIZE.Description"));
defaultZoom.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
double x = defaultZoomToModel(defaultZoom.getValue());
defaultZoomDisplay.setText(String.format("%.2fx", x));
}
});
settings.add(defaultZoom, gbc);
gbc.gridwidth = 1;
gbc.gridy = 0;
gbc.gridx = 2;
gbc.gridwidth = 2;
shortTasks = new JCheckBox(I18N.getInstance().getString(
"Model.Settings.Type.USE_SHORT_TASK_NAMES_IF_AVAILABLE"));
shortTasks
.setToolTipText(I18N
.getInstance()
.getString(
"Model.Settings.Type.USE_SHORT_TASK_NAMES_IF_AVAILABLE.Description"));
settings.add(shortTasks, gbc);
gbc.gridwidth = 1;
gbc.gridy = 1;
gbc.gridx = 2;
gbc.gridwidth = 2;
defaultParamExport = new JCheckBox(I18N.getInstance().getString(
"Model.Settings.Type.EXPORT_PARAMETERS_WITH_DEFAULT_VALUES"));
defaultParamExport
.setToolTipText(I18N
.getInstance()
.getString(
"Model.Settings.Type.EXPORT_PARAMETERS_WITH_DEFAULT_VALUES.Description"));
settings.add(defaultParamExport, gbc);
gbc.gridwidth = 1;
gbc.gridy = 2;
gbc.gridx = 2;
gbc.gridwidth = 2;
showStartup = new JCheckBox(I18N.getInstance().getString(
"Model.Settings.Type.SHOW_STARTUP_SCREEN"));
showStartup.setToolTipText(I18N.getInstance().getString(
"Model.Settings.Type.SHOW_STARTUP_SCREEN.Description"));
settings.add(showStartup, gbc);
gbc.gridwidth = 1;
gbc.gridy = 3;
gbc.gridx = 2;
settings.add(
new JLabel(I18N.getInstance().getString(
"Model.Settings.Type.MAXIMUM_UNDO_STEPS")
+ ":"), gbc);
gbc.gridx = 3;
maxUndoSteps = new JSpinner();
maxUndoSteps.setPreferredSize(new Dimension(minSpinnerWidth,
maxUndoSteps.getPreferredSize().height));
maxUndoSteps.setToolTipText(I18N.getInstance().getString(
"Model.Settings.Type.MAXIMUM_UNDO_STEPS.Description"));
settings.add(maxUndoSteps, gbc);
gbc.gridy = 6;
gbc.gridx = 2;
rasterSizeEnable = new JCheckBox(I18N.getInstance().getString(
"Model.Settings.Type.PIPELINE_RASTER_SIZE")
+ ":");
rasterSizeEnable.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
rasterSize.setEnabled(rasterSizeEnable.isSelected());
}
});
settings.add(rasterSizeEnable, gbc);
gbc.gridx = 3;
rasterSizeDisplay = new JLabel("");
settings.add(rasterSizeDisplay, gbc);
gbc.gridy = 7;
gbc.gridx = 2;
gbc.gridwidth = 2;
rasterSize = new JSlider(1, 100);
rasterSize.setMajorTickSpacing(10);
rasterSize.setMinorTickSpacing(1);
rasterSize.setPaintTicks(true);
rasterSize.setPaintLabels(false);
rasterSize.setSnapToTicks(true);
rasterSize.setToolTipText(I18N.getInstance().getString(
"Model.Settings.Type.PIPELINE_RASTER_SIZE.Description"));
rasterSize.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
int x = rasterSizeToModel(rasterSize.getValue());
rasterSizeDisplay.setText(String.valueOf(x) + " px");
}
});
settings.add(rasterSize, gbc);
gbc.gridwidth = 1;
add(settings, BorderLayout.CENTER);
pack();
centerWindow();
}
@Override
public boolean shallApplyChanges() {
return this.applyChanges;
}
@Override
public void setLocales(Locale[] locales) {
this.locales = locales;
String[] localeStrings = new String[locales.length];
for (int i = 0; i < locales.length; i++) {
localeStrings[i] = locales[i].getDisplayLanguage();
}
language.setModel(new DefaultComboBoxModel(localeStrings));
}
/**
* Translates a JSlider value in [1,200] to a modelValue of (0,10].
*
* @param viewValue
* the slider position in [1,200]
* @return the modelValue in (0,2]
*/
private double defaultZoomToModel(int viewValue) {
return (double) viewValue / 100.0;
}
/**
* Translates a modelValue of (0,2] to a JSlider value in [1,200].
*
* @param modelValue
* the modelValue in (0,2]
* @return the slider position in [0,200]
*/
private int defaultZoomFromModel(double modelValue) {
return (int) (100.0 * modelValue);
}
/**
* Translates a JSlider value of [0,100] to a model value in [0,500]
*
* @param viewValue
* JSlider value in [0,100]
* @return the the modelValue in [0,500]
*/
private int rasterSizeToModel(int viewValue) {
if (!rasterSizeEnable.isSelected()) {
return 0;
} else {
return 5 * rasterSize.getValue();
}
}
/**
* Translates a modelValue of [0,500] to a JSlider value in [0,100]
*
* @param viewValue
* the modelValue in [0,500]
* @return the JSlider value in [0,100]
*/
private int rasterSizeFromModel(int modelValue) {
return modelValue / 5;
}
@Override
public Object getValue(SettingType type) {
switch (type) {
case DEFAULT_OSMOSIS_PATH:
return this.osmosisPath.getValue();
case DEFAULT_JOSM_PATH:
return this.josmPath.getValue();
case DEFAULT_WORKING_DIRECTORY:
return this.workingPath.getValue();
case ACTIVE_LANGUAGE:
int selected = this.language.getSelectedIndex();
return (selected >= 0) ? this.locales[this.language
.getSelectedIndex()] : null;
case DEFAULT_ZOOM_SIZE:
int x = defaultZoom.getValue();
return defaultZoomToModel(x);
case USE_SHORT_TASK_NAMES_IF_AVAILABLE:
return this.shortTasks.isSelected();
case EXPORT_PARAMETERS_WITH_DEFAULT_VALUES:
return this.defaultParamExport.isSelected();
case MAXIMUM_UNDO_STEPS:
return this.maxUndoSteps.getValue();
case PIPELINE_RASTER_SIZE:
int y = this.rasterSize.getValue();
return rasterSizeToModel(y);
case SHOW_STARTUP_SCREEN:
return this.showStartup.isSelected();
case UPDATE_INTERVAL:
switch (this.updateInterval.getSelectedIndex()) {
case 1:
return SettingsTypeUpdateInterval.ONCE_A_DAY;
case 2:
return SettingsTypeUpdateInterval.ONCE_A_WEEK;
default:
return SettingsTypeUpdateInterval.NEVER;
}
case ACTIVE_PLAF:
return this.pLaF.getSelectedItem();
default:
return null;
}
}
@Override
public void setValue(SettingType type, Object value) {
switch (type) {
case DEFAULT_OSMOSIS_PATH:
this.osmosisPath.setValue((String) value);
break;
case DEFAULT_JOSM_PATH:
this.josmPath.setValue((String) value);
break;
case DEFAULT_WORKING_DIRECTORY:
this.workingPath.setValue((String) value);
break;
case ACTIVE_LANGUAGE:
Locale newLocale = (Locale) value;
for (int i = 0; i < locales.length; i++) {
if (locales[i].equals(newLocale)) {
this.language.setSelectedIndex(i);
return;
}
}
this.language.setSelectedIndex(-1);
break;
case DEFAULT_ZOOM_SIZE:
double x = (Double) value;
this.defaultZoom.setValue(0);
this.defaultZoom.setValue(defaultZoomFromModel(x));
break;
case USE_SHORT_TASK_NAMES_IF_AVAILABLE:
this.shortTasks.setSelected((Boolean) value);
break;
case EXPORT_PARAMETERS_WITH_DEFAULT_VALUES:
this.defaultParamExport.setSelected((Boolean) value);
break;
case MAXIMUM_UNDO_STEPS:
this.maxUndoSteps.setValue((Integer) value);
break;
case PIPELINE_RASTER_SIZE:
int rasterSize = rasterSizeFromModel((Integer) value);
this.rasterSizeEnable.setSelected(rasterSize != 0);
this.rasterSize.setEnabled(rasterSize != 0);
this.rasterSize.setValue(0);
this.rasterSize.setValue(rasterSize);
break;
case SHOW_STARTUP_SCREEN:
this.showStartup.setSelected((Boolean) value);
break;
case UPDATE_INTERVAL:
SettingsTypeUpdateInterval stui = (SettingsTypeUpdateInterval) value;
int newIndex = -1;
switch (stui) {
case NEVER:
newIndex = 0;
break;
case ONCE_A_DAY:
newIndex = 1;
break;
case ONCE_A_WEEK:
newIndex = 2;
break;
}
this.updateInterval.setSelectedIndex(newIndex);
break;
case ACTIVE_PLAF:
this.pLaF.setSelectedItem((String) value);
}
}
}