/* ========================
* 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-2005, by :
* Corporate:
* EADS Astrium SAS
* EADS CRC
* Individual:
* Claude Cazenave
*
* $Id: AbstractShapePropertiesDialogBox.java,v 1.5 2009/01/08 16:41:45 ogor Exp $
*
* Changes
* -------
* 22 ao�t 2006 : Initial public release (CC);
*
*/
package simtools.shapes.ui;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.event.UndoableEditEvent;
import javax.swing.undo.CompoundEdit;
import simtools.shapes.AbstractShape;
import simtools.shapes.ShapesContainer.ShapesDiagramComponent;
import simtools.ui.HeaderPanel;
import simtools.ui.JPropertiesPanel;
import simtools.ui.MenuResourceBundle;
import simtools.ui.ResourceFinder;
import simtools.ui.MessageDisplayer;
import simtools.util.NamedProperties;
/**
*
* Edit properties related to a set of shapes.
*
* The first shape is a reference.
* THe dialog box content is initialized with this reference properties
*
* When applying changes to the whole shapes, we take only in account
* the properties which have changed compared to the reference initial values.
* @author zxpletran007
*
*/
public class AbstractShapePropertiesDialogBox extends JDialog implements MessageDisplayer, ActionListener {
protected JButton bok, bclose, bapply;
protected JPropertiesPanel content;
protected List shapes;
protected ShapesDiagramComponent shapeComponent;
protected HeaderPanel headerPanel;
protected static MenuResourceBundle resources = ResourceFinder.getMenu(AbstractShapePropertiesDialogBox.class);
/**
* @param parent
* @param content
* @param title
* @param shapes
* @param shapeComponent
*/
public AbstractShapePropertiesDialogBox(Frame parent, JPropertiesPanel panel, String title, List shapes,
ShapesDiagramComponent shapeComponent) {
super(parent, title, false);
// Create content
headerPanel = new HeaderPanel();
content = panel;
content.setOwner(this);
content.setProperties( (AbstractShape)shapes.get(0) ); // Initalize content panel with first shape properties.
// Display content warnings on header panel
content.updateWarnings();
this.shapes = shapes;
this.shapeComponent = shapeComponent;
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(headerPanel, BorderLayout.NORTH);
contentPane.add(content, BorderLayout.CENTER);
contentPane.add(createButtonPanel(), BorderLayout.SOUTH);
if (JDialog.isDefaultLookAndFeelDecorated()) {
boolean supportsWindowDecorations = UIManager.getLookAndFeel().getSupportsWindowDecorations();
if (supportsWindowDecorations) {
setUndecorated(true);
getRootPane().setWindowDecorationStyle(JRootPane.QUESTION_DIALOG);
}
}
pack();
setLocationRelativeTo(parent);
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
}
protected JPanel createButtonPanel() {
JPanel p = new JPanel();
bapply = resources.getButton("applyButton", this);
bclose = resources.getButton("closeButton", this);
bok = resources.getButton("OKButton", this);
p.add(bok);
p.add(bapply);
p.add(bclose);
return p;
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == bok) {
setShapesProperties();
dispose();
} else if (e.getSource() == bapply) {
setShapesProperties();
repaint();
} else if (e.getSource() == bclose) {
dispose();
}
}
protected void setShapesProperties(){
// Get properties that have changed
List changedProperties = new ArrayList();
AbstractShape shapeReference = (AbstractShape)shapes.get(0);
String[] contentsProperties = content.getPropertyNames();
for(int i=0; i < contentsProperties.length; i++){
Object newValue = content.getPropertyValue(contentsProperties[i]);
Object refValue = shapeReference.getPropertyValue(contentsProperties[i]);
if ( ( (newValue == null) && (refValue != null))
|| ( (newValue != null) && (refValue == null))
|| ( newValue!=null && refValue != null && !newValue.equals(refValue))
){
changedProperties.add(contentsProperties[i]);
}
}
// If some properties have changed, apply them to all shapes
if (!changedProperties.isEmpty()){
CompoundEdit shapesEdit = new CompoundEdit();
for(int i=0;i<shapes.size(); i++){
AbstractShape shape = (AbstractShape)shapes.get(i);
// Merge the changes with all shape properties before
ChangedProperties shapeProperties = new ChangedProperties();
String[] shapePropertiesName = shape.getPropertyNames();
for(int j=0; j < shapePropertiesName.length; j++){
String property = shapePropertiesName[j];
if (changedProperties.contains(property)){
shapeProperties.setPropertyValue(property, content.getPropertyValue(property));
} else {
shapeProperties.setPropertyValue(property, shape.getPropertyValue(property));
}
}
CompoundEdit ce = new CompoundEdit();
if (shape.setProperties(shapeProperties, ce)) {
shapesEdit.addEdit(ce);
}
ce.end();
}
shapesEdit.end();
if (shapesEdit.isSignificant()) {
shapeComponent.fireUndoableEditUpdate(new UndoableEditEvent(shapeComponent, shapesEdit));
shapeComponent.repaint();
}
}
}
public void dispose() {
AbstractShape.currentDialogBox = null;
super.dispose();
}
/**
* A Panel dedicated to display shape description or warnings/errors
* messages
*
* @author zxpletran007
*
*/
public HeaderPanel getHeaderPanel() {
return headerPanel;
}
/**
* This class holds properties to apply to a shape
* @author zxpletran007
*
*/
public static class ChangedProperties implements NamedProperties{
private LinkedHashMap changes;
public ChangedProperties(){
changes = new LinkedHashMap();
}
public Collection getInnerProperties() {
return null;
}
public String[] getPropertyNames() {
Set keys = changes.keySet();
String[] ret = new String[keys.size()];
int i=0;
for(Iterator it = keys.iterator(); it.hasNext();){
ret[i] = (String)it.next();
i++;
}
return ret;
}
public Object getPropertyValue(String name) {
return changes.get(name);
}
public void setPropertyValue(String name, Object value) {
changes.put(name, value);
}
}
/* (non-Javadoc)
* @see simtools.ui.MessageDisplayer#clearAllMessages()
*/
public void clearAllMessages() {
headerPanel.clearAllMessages();
}
public void displayError(String errorText) {
headerPanel.displayError(errorText);
}
public void displayWarning(String warningText) {
headerPanel.displayWarning(warningText);
}
}