/* ==============================================
* Simtools : The tools library used in JSynoptic
* ==============================================
*
* Project Info: http://jsynoptic.sourceforge.net/index.html
*
* This library 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 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2001-2003, by :
* Corporate:
* Astrium SAS
* EADS CRC
* Individual:
* Nicolas Brodu
*
* $Id: SourceTree.java,v 1.31 2008/10/03 12:33:06 ogor Exp $
*
* Changes
* -------
* 30-Mar-2004 : Extracted generic part from JSynoptic into Simtools (NB)
*
*/
package jsynoptic.ui;
import java.awt.Component;
import java.awt.Point;
import java.awt.SystemColor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.Vector;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellRenderer;
import jsynoptic.base.ContextualActionProvider;
import jsynoptic.data.DataSourceAnimator;
import jsynoptic.data.DataSourceCollectionAnimator;
import jsynoptic.data.ExpressionDataSource;
import simtools.data.DataException;
import simtools.data.DataInfo;
import simtools.data.DataSource;
import simtools.data.DataSourceCollection;
import simtools.data.DataSourcePool;
import simtools.data.DataSourcePoolListener;
import simtools.data.DynamicDataSourceCollection;
import simtools.diagram.DiagramComponent;
import simtools.ui.BasicMessageWriter;
import simtools.ui.DataSourceInformationDialog;
import simtools.ui.MenuResourceBundle;
import simtools.ui.ResourceFinder;
/**
* Tree widget specialized in displaying data sources. Uses and listens to the
* data source pool of JSynoptic.
*
* @author Nicolas Brodu
*
* @version 1.0 2001
*/
public class SourceTree extends simtools.ui.SourceTree implements DataSourcePoolListener, ActionListener {
/** Resources */
public static MenuResourceBundle resources = ResourceFinder.getMenu(SourceTree.class);
public static BasicMessageWriter messageWriter = ResourceFinder.getMessages(SourceTree.class);
protected static HashMap dataSourceIcons;
static {
Icon expressionIcon = resources.getIcon("expIcon");
Icon dynamicSourceIcon = resources.getIcon("dynamicSourceIcon");
Icon dynamicSourceCollectionIcon = resources.getIcon("dynamicSourceCollectionIcon");
dataSourceIcons = new HashMap();
dataSourceIcons.put(ExpressionDataSource.class, expressionIcon);
dataSourceIcons.put(DataSourceAnimator.class, dynamicSourceIcon);
dataSourceIcons.put(DataSourceCollectionAnimator.class, dynamicSourceCollectionIcon);
dataSourceIcons.put(DynamicDataSourceCollection.class, dynamicSourceCollectionIcon);
sourceTreeClass = SourceTree.class;
}
static void addSourceIcons(Object[][] classAndIcons) {
for (int i = 0; i < classAndIcons.length; i++) {
dataSourceIcons.put(classAndIcons[i][0], classAndIcons[i][1]);
}
}
public SourceTree(DataSourcePool pool) {
super(pool);
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
if ((e.getModifiers() & InputEvent.BUTTON1_MASK) == InputEvent.BUTTON1_MASK) {
DiagramComponent d = JSynoptic.gui.getActiveComponent();
if (d != null) {
if (!d.getDiagramSelection().isEmpty()) {
d.getDiagramSelection().unselect();
d.repaint();
}
}
}
}
});
}
public SourceTree() {
this(DataSourcePool.global);
}
protected void doPopup(int x, int y) {
ShapesContainer sc = JSynoptic.gui.getActiveContainer();
JPopupMenu popup;
if (sc == null) {
popup = new JPopupMenu();
} else {
DiagramComponent dc = sc.getComponent();
if (dc == null) {
return;
}
if (!(dc instanceof ShapesContainer.ShapesComponent)) {
return;
}
ShapesContainer.ShapesComponent sco = (ShapesContainer.ShapesComponent) dc;
if ((getSelectionPath() == null) && sco.isSelectionEmpty()) {
JSynoptic.setStatus(messageWriter.print0args("noSelection"));
return;
}
Point dcLoc = sco.getLocationOnScreen();
Point myLoc = getLocationOnScreen();
int sx = x + myLoc.x - dcLoc.x;
int sy = y + myLoc.y - dcLoc.y;
if (sco.isSelectionEmpty()) {
popup = new JPopupMenu();
} else {
popup = sco.doPopup(sx, sy, ContextualActionProvider.SOURCELIST_CONTEXT);
popup.addSeparator();
}
}
if (sourceInfo == null) {
sourceInfo = resources.getItem("sourceInfo", this);
}
popup.add(sourceInfo);
if (sourceDelete == null) {
sourceDelete = resources.getItem("sourceDelete", this);
}
Object o = getSelectedSourceOrCollection();
if ( (o != null) && (!isLocked(o)) && selectionIsRootChild()) {
popup.add(sourceDelete);
}
Object sel = getSelectedSourceOrCollection();
if ((sel != null) && (sel instanceof ContextualActionProvider)) {
ContextualActionProvider provider = (ContextualActionProvider) sel;
String[] actions = provider.getActions(x, y, sel, ContextualActionProvider.SOURCELIST_CONTEXT);
if ((actions != null) && (actions.length != 0)) {
for (int i = 0; i < actions.length; ++i) {
JMenuItem jmi = new JMenuItem(actions[i]);
if (!provider.canDoAction(x, y, sel, actions[i], ContextualActionProvider.SOURCELIST_CONTEXT)) {
jmi.setEnabled(false);
} else {
jmi.addActionListener(this);
}
add(jmi);
popup.add(jmi);
}
}
}
actionX = y;
actionY = y;
popup.show(this, x, y);
}
// ActionListener interface
public void actionPerformed(ActionEvent e) {
if (e.getSource() == sourceDelete) {
Object o = getSelectedSourceOrCollection();
if (o == null) {
return;
} if (isLocked(o)) {
return;
} else if (o instanceof DataSource) {
pool.removeDataSource((DataSource)o);
} else if (o instanceof DataSourceCollection) {
pool.removeDataSourceCollection((DataSourceCollection)o);
}
} else if (e.getSource() == sourceInfo) {
Object o = getSelectedSourceOrCollection();
if (o == null) {
return;
}
if (o instanceof DataSource) {
try {
DataSourceInformationDialog di = new DataSourceInformationDialog((DataSource) o);
JDialog jd = di.createDialog(JSynoptic.gui.getOwner());
if (jd != null) {
jd.setVisible(true);
}
} catch (DataException ee) {
JSynoptic.setStatus(ee.getMessage());
}
return;
}
Vector infos = new Vector();
if (DataInfo.getLabel(o) != null) {
infos.add(messageWriter.print1args("sourceName", DataInfo.getLabel(o)));
}
if (DataInfo.getId(o) != null) {
infos.add(messageWriter.print1args("sourceId", DataInfo.getId(o)));
}
if (DataInfo.getComment(o) != null) {
infos.add(messageWriter.print1args("sourceComment", DataInfo.getComment(o)));
}
if (DataInfo.getUnit(o) != null) {
infos.add(messageWriter.print1args("sourceUnit", DataInfo.getUnit(o)));
}
if (DataInfo.getUnit(o) != null) {
infos.add(messageWriter.print1args("displayFormat", DataInfo.getPrintfFormat(o)).toString());
}
if (DataInfo.getLinkedId(o) != null) {
infos.add(messageWriter.print1args("sourceLinkedId", DataInfo.getLinkedId(o)));
}
if (infos.size() == 0) {
JSynoptic.setStatus(messageWriter.print0args("noInfo"));
return;
}
JOptionPane.showMessageDialog(JSynoptic.gui.getOwner(), infos.toArray(), messageWriter
.print0args("sourceInfo"), JOptionPane.INFORMATION_MESSAGE);
return;
}
if (e.getSource() instanceof JMenuItem) {
JMenuItem jmi = (JMenuItem) e.getSource();
Object o = getSelectedSourceOrCollection();
if (!(o instanceof ContextualActionProvider)) {
return;
}
if (o instanceof ContextualActionProvider) {
((ContextualActionProvider) o).doAction(actionX, actionY, o, jmi.getText(), null);
}
return;
}
super.actionPerformed(e);
}
protected TreeCellRenderer createRenderer() {
return new SourceCellRenderer();
}
class SourceCellRenderer extends DefaultTreeCellRenderer {
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded,
boolean leaf, int row, boolean hasFocus) {
Component c = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
if (value == null) {
return c;
}
if (value instanceof SourceNode) {
Object o = ((SourceNode) value).getUserObject();
if (o instanceof ExpressionDataSource) {
setText(DataInfo.toString(o) + " = " + DataInfo.getComment(o));
}
Icon icon = (Icon) dataSourceIcons.get(o.getClass());
if (icon != null) {
setIcon(icon);
} else {
Class parent = o.getClass().getSuperclass();
if (parent != null) {
icon = (Icon) dataSourceIcons.get(parent);
if (icon != null) {
setIcon(icon);
}
}
}
if (((SourceNode) value).isLocked()) {
c.setForeground(SystemColor.controlDkShadow);
}
}
return c;
}
}
}