/**
*
*/
package cz.cuni.mff.peckam.java.origamist.configuration;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.net.URL;
import java.util.Locale;
import java.util.ResourceBundle;
import cz.cuni.mff.peckam.java.origamist.math.AngleUnit;
import cz.cuni.mff.peckam.java.origamist.model.jaxb.Unit;
import cz.cuni.mff.peckam.java.origamist.services.ServiceLocator;
import cz.cuni.mff.peckam.java.origamist.services.interfaces.ConfigurationManager;
import cz.cuni.mff.peckam.java.origamist.utils.ObservableList;
import cz.cuni.mff.peckam.java.origamist.utils.PropertyChangeSource;
import cz.cuni.mff.peckam.java.origamist.utils.UnitDimensionWithLabel;
/**
* A configuration of the program.
*
* Properties that fire PropertyChangeEvent when they are changed:
* locale
* diagramLocale
* lastExportPath
* preferredUnit
* defaultAuthorName
* defaultAuthorHomepage
*
* @author Martin Pecka
*/
public class Configuration extends PropertyChangeSource
{
/**
* General locale of the program.
*/
protected Locale locale = Locale.getDefault();
/**
* The preferred locale for diagrams. If null, means that it is the same as
* locale.
*/
protected Locale diagramLocale = null;
/** The path that was last used for exporting a model/listing. */
protected File lastExportPath = null;
/** The path that was last used for opening a model/listing. */
protected File lastOpenPath = null;
/** The URL that was last used for opening a model/listing. */
protected URL lastOpenURL = null;
/**
* The preferred measurement unit. <code>null</code> means that the unit defined in the corresponding
* {@link cz.cuni.mff.peckam.java.origamist.model.UnitDimension} should be used for printing.
*/
protected Unit preferredUnit = null;
/** The name the author uses for diagrams created by him/her. */
protected String defaultAuthorName = null;
/** The homepage the author uses for diagrams created by him/her. */
protected String defaultAuthorHomepage = null;
/** The list of user-defined papers. */
protected ObservableList<UnitDimensionWithLabel> papers = new ObservableList<UnitDimensionWithLabel>();
/** The preferred angle unit. */
protected AngleUnit preferredAngleUnit = null;
/**
* @return the locale
*/
public Locale getLocale()
{
return locale;
}
/**
* @param locale the locale to set
*/
public void setLocale(Locale locale)
{
Locale oldLocale = this.locale;
this.locale = locale;
firePropertyChange("locale", oldLocale, locale);
}
/**
* @return the diagramLocale
*/
public Locale getDiagramLocale()
{
return diagramLocale == null ? locale : diagramLocale;
}
/**
* @param diagramLocale the diagramLocale to set
*/
public void setDiagramLocale(Locale diagramLocale)
{
Locale oldLocale = this.diagramLocale;
this.diagramLocale = diagramLocale;
firePropertyChange("diagramLocale", oldLocale, diagramLocale);
}
/**
* @return the lastExportPath
*/
public File getLastExportPath()
{
return lastExportPath;
}
/**
* @param lastExportPath the lastExportPath to set
*/
public void setLastExportPath(File lastExportPath)
{
File oldPath = this.lastExportPath;
this.lastExportPath = lastExportPath;
firePropertyChange("lastExportPath", oldPath, lastExportPath);
}
/**
* @return the lastOpenPath
*/
public File getLastOpenPath()
{
return lastOpenPath;
}
/**
* @param lastOpenPath the lastOpenPath to set
*/
public void setLastOpenPath(File lastOpenPath)
{
File oldPath = this.lastOpenPath;
this.lastOpenPath = lastOpenPath;
firePropertyChange("lastOpenPath", oldPath, lastOpenPath);
}
/**
* @return the lastOpenURL
*/
public URL getLastOpenURL()
{
return lastOpenURL;
}
/**
* @param lastOpenURL the lastOpenURL to set
*/
public void setLastOpenURL(URL lastOpenURL)
{
URL oldURL = this.lastOpenURL;
this.lastOpenURL = lastOpenURL;
firePropertyChange("lastOpenURL", oldURL, lastOpenURL);
}
/**
* @return The preferred measurement unit. <code>null</code> means that the unit defined in the corresponding
* {@link cz.cuni.mff.peckam.java.origamist.model.UnitDimension} should be used for printing.
*/
public Unit getPreferredUnit()
{
return preferredUnit;
}
/**
* @param preferredUnit The preferred measurement unit. <code>null</code> means that the unit defined in the
* corresponding {@link cz.cuni.mff.peckam.java.origamist.model.UnitDimension} should be used for
* printing.
*/
public void setPreferredUnit(Unit preferredUnit)
{
Unit oldUnit = this.preferredUnit;
this.preferredUnit = preferredUnit;
firePropertyChange("preferredUnit", oldUnit, preferredUnit);
}
/**
* @return The preferred angle unit.
*/
public AngleUnit getPreferredAngleUnit()
{
if (preferredAngleUnit == null)
setPreferredAngleUnit(AngleUnit.DEGREE);
return preferredAngleUnit;
}
/**
* @param preferredAngleUnit The preferred angle unit.
*/
public void setPreferredAngleUnit(AngleUnit preferredAngleUnit)
{
AngleUnit oldUnit = this.preferredAngleUnit;
this.preferredAngleUnit = preferredAngleUnit;
firePropertyChange("preferredAngleUnit", oldUnit, preferredAngleUnit);
}
/**
* @return the defaultAuthorName
*/
public String getDefaultAuthorName()
{
return defaultAuthorName;
}
/**
* @param defaultAuthorName the defaultAuthorName to set
*/
public void setDefaultAuthorName(String defaultAuthorName)
{
String oldName = this.defaultAuthorName;
this.defaultAuthorName = defaultAuthorName;
firePropertyChange("defaultAuthorName", oldName, defaultAuthorName);
}
/**
* @return the defaultAuthorHomepage
*/
public String getDefaultAuthorHomepage()
{
return defaultAuthorHomepage;
}
/**
* @param defaultAuthorHomepage the defaultAuthorHomepage to set
*/
public void setDefaultAuthorHomepage(String defaultAuthorHomepage)
{
String oldHomepage = this.defaultAuthorHomepage;
this.defaultAuthorHomepage = defaultAuthorHomepage;
firePropertyChange("defaultAuthorHomepage", oldHomepage, defaultAuthorHomepage);
}
/**
* @return the papers
*/
public ObservableList<UnitDimensionWithLabel> getPapers()
{
return papers;
}
/**
* Adds a {@link ResourceBundleKeyListener} as a {@link PropertyChangeListener} and runs it with the current locale.
*
* @param l The listener to add.
*/
public void addAndRunResourceBundleListener(ResourceBundleListener l)
{
addPropertyChangeListener(l.getPropertyName(), l);
l.propertyChange(new PropertyChangeEvent(this, l.getPropertyName(), null, l.getProperty()));
}
/**
* A listener that calls <code>bundleChanged</code> whenever the locale <code>propertyName</code> changes.
*
* @author Martin Pecka
*/
public abstract static class ResourceBundleListener implements PropertyChangeListener
{
/** The bundle to monitor. */
protected String bundleName;
/** The name of the property of the monitored {@link Locale}. */
protected String propertyName;
/** The actual resource bundle. */
protected ResourceBundle bundle;
/** Configuration for static access "hacking". */
protected Configuration config = ServiceLocator.get(ConfigurationManager.class).get();
/**
* @param bundleName The bundle to monitor.
* @param propertyName The name of the property of the monitored {@link Locale}.
*/
public ResourceBundleListener(String bundleName, String propertyName)
{
this.bundleName = bundleName;
this.propertyName = propertyName;
}
/**
* Called when the resource bundle changes.
*/
public abstract void bundleChanged();
@Override
public void propertyChange(PropertyChangeEvent evt)
{
bundle = ResourceBundle.getBundle(bundleName, getProperty());
bundleChanged();
}
/**
* @return The name of the property of the monitored {@link Locale}.
*/
public String getPropertyName()
{
return propertyName;
}
/**
* @return The monitored {@link Locale}.
*/
public abstract Locale getProperty();
}
/**
* A listener for changes of the locale configuration.
*
* @author Martin Pecka
*/
public abstract static class ResourceBundleLocaleListener extends ResourceBundleListener
{
/**
* @param bundleName The bundle to monitor.
*/
public ResourceBundleLocaleListener(String bundleName)
{
super(bundleName, "locale");
}
@Override
public Locale getProperty()
{
return config.locale;
}
}
/**
* A listener that calls <code>updateText</code> for the given <code>key</code> from a <code>resourceBundle</code>
* whenever the locale <code>propertyName</code> changes.
*
* @author Martin Pecka
*/
public abstract static class ResourceBundleKeyListener extends ResourceBundleListener
{
/** The key from the monitored bundle. */
protected String key;
/**
* @param bundleName The bundle to monitor.
* @param key The key from the monitored bundle.
* @param propertyName The name of the property of the monitored {@link Locale}.
*/
protected ResourceBundleKeyListener(String bundleName, String key, String propertyName)
{
super(bundleName, propertyName);
this.key = key;
}
/**
* Called when the resource bundle changes.
*
* @param text The translated text.
*/
protected abstract void updateText(String text);
@Override
public void bundleChanged()
{
updateText(bundle.getString(key));
}
}
/**
* A listener monitoring changes to <code>locale</code> and reading <code>key</code> from a
* <code>resourceBundle</code> whenever the locale changes.
*
* @author Martin Pecka
*/
public abstract static class LocaleListener extends ResourceBundleKeyListener
{
/**
* @param bundleName The bundle to monitor.
* @param key The key from the monitored bundle.
*/
protected LocaleListener(String bundleName, String key)
{
super(bundleName, key, "locale");
}
@Override
public Locale getProperty()
{
return config.getLocale();
}
}
}