/* ========================
* JSynoptic : a free Synoptic editor
* ========================
*
* Project Info: http://jsynoptic.sourceforge.net/index.html
*
* 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 2.1 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 along with this
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2001-2006, by :
* Corporate:
* EADS Astrium SAS
* Individual:
* Mathias Choquet
*
*
* $Id$
*
*/
package jsynoptic.plugins.svg.ui;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ResourceBundle;
import javax.swing.ButtonGroup;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.filechooser.FileFilter;
import jsynoptic.builtin.ui.PropertiesPanel2D;
import jsynoptic.plugins.svg.SvgImagePreview;
import jsynoptic.plugins.svg.SvgMapper;
import jsynoptic.plugins.svg.SvgShape;
import jsynoptic.plugins.svg.SvgShape.SvgShapePropertiesNames;
import jsynoptic.ui.Run;
import simtools.data.DataInfo;
import simtools.data.DataSource;
import simtools.ui.ActionCheckBox;
import simtools.ui.BasicMessageWriter;
import simtools.ui.FilteredSourceTree;
import simtools.ui.GridBagPanel;
import simtools.ui.ResourceFinder;
import simtools.util.CurrentPathProvider;
/**
* Class SvgShapePropertiesPanel. Summary: Properties panel for SvgShape
*/
public class SvgShapePropertiesPanel extends PropertiesPanel2D {
public static JFileChooser fileChooser = null;
protected JLabel cmLabel;
protected JList cmlist;
protected JButton cmNew;
protected JButton cmDelete;
protected JButton cmDuplicate;
protected JLabel dsLabel;
protected JLabel lds;
protected FilteredSourceTree dstree;
protected ActionCheckBox cbDynamic;
protected JLabel lstatic;
protected JButton bChoose;
protected SvgImagePreview svgPreview;
protected JRadioButton rbFit, rbResize;
/**
* the file currently selected by the SvgShapePropertiesPanel
*/
protected File currentFile;
/**
* An optional default directory for SVG shapes
*/
public static File defaultDirectory = null;
static {
String defaultDirectoryName = Run.getProperties().getString(
"jsynoptic.plugins.svg.ui.SvgShapePropertiesPanel.defaultDirectory", null);
if (defaultDirectoryName != null) {
defaultDirectory = new File(defaultDirectoryName);
}
}
public static ResourceBundle resources = ResourceFinder.get(SvgShape.class);
public static BasicMessageWriter messageWriter = ResourceFinder.getMessages(SvgShape.class);
/**
* the mapper of the SvgShapePropertiesPanel
*/
protected SvgMapper mapper;
/**
* the Datasource selected by the SvgShapePropertiesPanel
*/
protected DataSource source;
protected GridBagPanel dynamicImagePanel, staticImagePanel;
/**
* Constructor. empty constructor, call the createContent method
*/
public SvgShapePropertiesPanel(String shapeName) {
super(true, true, true, true, shapeName);
setStaticImagePanel();
setDynamicImagePanel();
addOnCurrentRow(staticImagePanel, 2, false, true, true);
addOnCurrentRow(dynamicImagePanel, 2, true, true, true);
}
public void setDynamicImagePanel() {
cbDynamic = new ActionCheckBox(resources.getString("UseDynamicImages")) {
public void actionPerformed(ActionEvent e) {
cmLabel.setEnabled(isSelected());
dsLabel.setEnabled(isSelected());
cmlist.setEnabled(isSelected());
cmNew.setEnabled(isSelected());
cmDelete.setEnabled((isSelected()) && (cmlist.getSelectedValue() != null));
cmDuplicate.setEnabled((isSelected()) && (cmlist.getSelectedValue() != null));
dstree.setEnabled(isSelected());
lds.setEnabled(isSelected());
updateWarnings();
}
};
cmLabel = new JLabel(resources.getString("ChooseAnImageMapper"));
cmLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
final SvgMapperListModel listModel = new SvgMapperListModel();
// Create the list and put it in a scroll pane.
cmlist = new JList(listModel);
cmlist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
cmlist.setVisibleRowCount(5);
JScrollPane cmlistScrollPane = new JScrollPane(cmlist);
cmNew = new JButton(resources.getString("New"));
cmDelete = new JButton(resources.getString("Delete"));
cmDuplicate = new JButton(resources.getString("Duplicate"));
dsLabel = new JLabel(resources.getString("ChooseADataSource"));
lds = new JLabel();
dstree = FilteredSourceTree.getFromPool("PropertiesPanel0");
dstree.getSourceTree().addTreeSelectionListener(new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent e) {
updateWarnings();
if (((dstree.getSelectedSourceOrCollection()) instanceof DataSource)
&& canSetDataSource((DataSource) dstree.getSelectedSourceOrCollection())) {
lds.setText(DataInfo.getId(dstree.getSelectedSourceOrCollection()));
}
}
});
cmNew.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
SvgMapper im = SvgMapper.createSvgMapperDialog(SvgShapePropertiesPanel.this.getOwner());
if (im == null) {
return;
}
if (SvgMapper.svgMappers == null) {
SvgMapper.svgMappers = new ArrayList();
}
if (SvgMapper.svgMappers.contains(im)) {
String[] message = new String[] { messageWriter.print1args("ReplaceExistingSvgMapperNamed?", im
.toString()) };
int answer = JOptionPane.showConfirmDialog(SvgShapePropertiesPanel.this.getOwner(), message,
messageWriter.print0args("MapperAlreadyExists!"), JOptionPane.YES_NO_OPTION);
if (answer == JOptionPane.YES_OPTION) {
// Object.equals is magic...
int index = SvgMapper.svgMappers.indexOf(im);
SvgMapper.svgMappers.set(index, im);
listModel.update();
cmlist.setSelectedValue(im, true);
}
return;
}
SvgMapper.svgMappers.add(im);
listModel.update();
cmlist.setSelectedValue(im, true);
}
});
cmDelete.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Object o = cmlist.getSelectedValue();
if (o == null) {
return;
}
if (SvgMapper.svgMappers != null) {
SvgMapper.svgMappers.remove(o);
}
listModel.update();
updateWarnings();
}
});
cmDelete.setEnabled(false);
cmDuplicate.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Object o = cmlist.getSelectedValue();
if ((o == null) || !(o instanceof SvgMapper)) {
return;
}
try{
SvgMapper im = (SvgMapper)((SvgMapper)o).clone();
if (SvgMapper.svgMappers != null) {
SvgMapper.svgMappers.add(im);
}
listModel.update();
}catch (CloneNotSupportedException cnse){
}
}
});
cmDuplicate.setEnabled(false);
cmlist.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
cmDelete.setEnabled(cmlist.getSelectedValue() != null);
cmDuplicate.setEnabled(cmlist.getSelectedValue() != null);
updateWarnings();
}
});
cmlist.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
int index = cmlist.locationToIndex(e.getPoint());
((SvgMapper) SvgMapper.svgMappers.get(index)).editDialog(SvgShapePropertiesPanel.this.getOwner());
}
}
});
dynamicImagePanel = new GridBagPanel(resources.getString("UseDynamicImages"));
dynamicImagePanel.addOnCurrentRow(cbDynamic, 4);
dynamicImagePanel.addOnCurrentRow(lds, 4);
dynamicImagePanel.carriageReturn();
dynamicImagePanel.addOnCurrentRow(cmLabel, 4);
dynamicImagePanel.addOnCurrentRow(dsLabel, 4);
dynamicImagePanel.carriageReturn();
dynamicImagePanel.addOnCurrentRow(cmlistScrollPane, 4, true, true, false);
dynamicImagePanel.addOnCurrentRow(dstree, 4, true, true, true);
dynamicImagePanel.addOnCurrentRow(cmNew);
dynamicImagePanel.addOnCurrentRow(cmDelete);
dynamicImagePanel.addOnCurrentRow(cmDuplicate);
}
public void setStaticImagePanel() {
currentFile = null;
rbFit = new JRadioButton(resources.getString("ScaleImageToFitObjectSize"), false);
rbResize = new JRadioButton(resources.getString("ChangeObjectSizeToFitImage"), false);
ButtonGroup bg = new ButtonGroup();
bg.add(rbFit);
bg.add(rbResize);
lstatic = new JLabel();
if (currentFile != null) {
lstatic.setText(currentFile.getName());
}
bChoose = new JButton(resources.getString("Choose"));
bChoose.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Set up the file chooser.
if (fileChooser == null) {
fileChooser = new JFileChooser();
// Add a custom file filter and disable the default
fileChooser.setAcceptAllFileFilterUsed(false);
// add the optionnal (Accept All) file filter.
fileChooser.addChoosableFileFilter(new SvgFileFilter());
// Add the preview pane.
fileChooser.setAccessory(svgPreview = new SvgImagePreview(fileChooser));
File svgDirectory = ((defaultDirectory != null) && defaultDirectory.exists()) ? defaultDirectory
: CurrentPathProvider.currentPathProvider.getCurrentPath();
fileChooser.setCurrentDirectory(svgDirectory);
}
fileChooser.setSelectedFile(currentFile);
// Show it.
int returnVal = fileChooser.showDialog(SvgShapePropertiesPanel.this.getOwner(), resources
.getString("SelectImage"));
// Process the results.
if (returnVal == JFileChooser.APPROVE_OPTION) {
currentFile = fileChooser.getSelectedFile();
if (currentFile != null) {
// get the name of the image
lstatic.setText(currentFile.getName());
// get the original size of the image
if (rbResize.isSelected()) {
BufferedImage originalImage = SvgShape.factory.get(currentFile);
if (originalImage != null) {
nfWidth.setValue(originalImage.getWidth());
nfHeight.setValue(originalImage.getHeight());
}
}
}
}
if (svgPreview != null) {
svgPreview.clean();
}
}
});
rbResize.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
if (rbResize.isSelected()) {
if (currentFile != null) {
BufferedImage originalImage = SvgShape.factory.get(currentFile);
if (originalImage != null) {
nfWidth.setValue(originalImage.getWidth());
nfHeight.setValue(originalImage.getHeight());
}
}
}
}
});
// Create panels
staticImagePanel = new GridBagPanel();
staticImagePanel.addOnCurrentRow(bChoose, 2);
staticImagePanel.addOnCurrentRow(lstatic);
staticImagePanel.carriageReturn();
staticImagePanel.addOnCurrentRow(rbFit, 2);
staticImagePanel.addOnCurrentRow(rbResize, 2);
staticImagePanel.carriageReturn();
}
protected String lineColorChooserTitle() {
return resources.getString("ChooseTheFrameColor");
}
protected String lineColorLabel() {
return resources.getString("DisplayFrame");
}
protected boolean canSetDataSource(DataSource ds) {
return true;
}
/*
* (non-Javadoc)
*
* @see jsynoptic.builtin.ui.PropertiesPanel1D#updateWarnings()
*/
public boolean updateWarnings() {
boolean res = false;
if (cbDynamic.isSelected()) {
if (cmlist.getSelectedValue() == null) {
displayWarning(resources.getString("selectAnImageMapper"));
res = true;
} else if (!(dstree.getSelectedSourceOrCollection() instanceof DataSource)) {
displayWarning(resources.getString("selectADataSource"));
res = true;
}
}
if (!res) {
res = super.updateWarnings();
}
return res;
}
protected static class SvgMapperListModel extends DefaultListModel {
SvgMapperListModel() {
fillFromMainList();
}
public void update() {
this.clear();
fillFromMainList();
}
protected void fillFromMainList() {
if (SvgMapper.svgMappers != null) {
for (Iterator it = SvgMapper.svgMappers.iterator(); it.hasNext();) {
addElement(it.next());
}
}
}
}
public String[] getPropertyNames() {
if (_propertyNames == null) {
_propertyNames = new SvgShapePropertiesNames().getPropertyNames();
}
return _propertyNames;
}
/*
* (non-Javadoc)
*
* @see simtools.ui.JPropertiesPanel#getPropertyValue(java.lang.String)
*/
public Object getPropertyValue(String name) {
Object res = super.getPropertyValue(name);
if (name.equalsIgnoreCase("SVG_FIT_TO_OBJECT")) {
res = new Boolean(rbFit.isSelected());
} else if (name.equalsIgnoreCase("SVG_FILE")) {
res = currentFile;
} else if (name.equalsIgnoreCase("SVG_MAPPER")) {
if (cbDynamic.isSelected()) {
res = cmlist.getSelectedValue();
}
} else if (name.equalsIgnoreCase("SVG_MAPPER_SOURCE")) {
if (cbDynamic.isSelected()) {
Object o = dstree.getSelectedSourceOrCollection();
if ((o instanceof DataSource) && canSetDataSource((DataSource) o)) {
res = o;
}
} else {
res = null;
}
}
return res;
}
/*
* (non-Javadoc)
*
* @see simtools.ui.JPropertiesPanel#setPropertyValue(java.lang.String,
* java.lang.Object)
*/
public void setPropertyValue(String name, Object value) {
super.setPropertyValue(name, value);
if (name.equalsIgnoreCase("SVG_FIT_TO_OBJECT")) {
if (value instanceof Boolean) {
rbFit.setSelected(((Boolean) value).booleanValue());
rbResize.setSelected(!rbFit.isSelected());
}
} else if (name.equalsIgnoreCase("SVG_FILE")) {
if (value instanceof File) {
currentFile = (File) value;
lstatic.setText(currentFile.getName());
}
} else if (name.equalsIgnoreCase("SVG_MAPPER")) {
if (value instanceof SvgMapper) {
mapper = (SvgMapper) value;
cmlist.setSelectedValue(mapper, true);
}
} else if (name.equalsIgnoreCase("SVG_MAPPER_SOURCE")) {
if ((value instanceof DataSource) && canSetDataSource((DataSource) value)) {
source = (DataSource) value;
lds.setText(DataInfo.getId(source));
} else {
source = null;
}
dstree.setSelectedValue(source);
cbDynamic.setSelected((source != null) || (mapper != null));
cbDynamic.apply();
}
}
/**
* Method <b>isSvgFile</b> test if the file is an svg file Parameters: the
* file f
*
* @return true if the parameter File f is a svg file (*.svg) false else
*/
public static class SvgFileFilter extends FileFilter {
public boolean accept(File f) {
return f.getName().endsWith(".svg") || f.isDirectory();
}
public String getDescription() {
// TODO do it with ressources
return "Just SVG Images";
}
}
}