/*
* Freeplane - mind map editor
* Copyright (C) 2008 Joerg Mueller, Daniel Polansky, Christian Foltin, Dimitry Polivaev
*
* This file is modified by Dimitry Polivaev in 2008.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.freeplane.features.styles.mindmapmode;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.plaf.basic.BasicButtonUI;
import org.freeplane.core.extension.IExtension;
import org.freeplane.core.resources.NamedObject;
import org.freeplane.core.resources.ResourceController;
import org.freeplane.core.resources.components.BooleanProperty;
import org.freeplane.core.resources.components.ColorProperty;
import org.freeplane.core.resources.components.ComboProperty;
import org.freeplane.core.resources.components.FontProperty;
import org.freeplane.core.resources.components.IPropertyControl;
import org.freeplane.core.resources.components.NextColumnProperty;
import org.freeplane.core.resources.components.NextLineProperty;
import org.freeplane.core.resources.components.NumberProperty;
import org.freeplane.core.resources.components.SeparatorProperty;
import org.freeplane.core.ui.AFreeplaneAction;
import org.freeplane.core.ui.components.UITools;
import org.freeplane.core.util.ColorUtils;
import org.freeplane.core.util.HtmlUtils;
import org.freeplane.core.util.TextUtils;
import org.freeplane.features.cloud.CloudController;
import org.freeplane.features.cloud.CloudModel;
import org.freeplane.features.cloud.mindmapmode.MCloudController;
import org.freeplane.features.edge.EdgeController;
import org.freeplane.features.edge.EdgeModel;
import org.freeplane.features.edge.EdgeStyle;
import org.freeplane.features.edge.mindmapmode.AutomaticEdgeColorHook;
import org.freeplane.features.edge.mindmapmode.MEdgeController;
import org.freeplane.features.format.FormatController;
import org.freeplane.features.format.IFormattedObject;
import org.freeplane.features.format.PatternFormat;
import org.freeplane.features.link.LinkController;
import org.freeplane.features.link.NodeLinks;
import org.freeplane.features.link.mindmapmode.MLinkController;
import org.freeplane.features.map.AMapChangeListenerAdapter;
import org.freeplane.features.map.IMapSelection;
import org.freeplane.features.map.INodeChangeListener;
import org.freeplane.features.map.INodeSelectionListener;
import org.freeplane.features.map.MapChangeEvent;
import org.freeplane.features.map.MapController;
import org.freeplane.features.map.MapModel;
import org.freeplane.features.map.NodeChangeEvent;
import org.freeplane.features.map.NodeModel;
import org.freeplane.features.mode.Controller;
import org.freeplane.features.mode.ModeController;
import org.freeplane.features.nodestyle.NodeSizeModel;
import org.freeplane.features.nodestyle.NodeStyleController;
import org.freeplane.features.nodestyle.NodeStyleModel;
import org.freeplane.features.nodestyle.mindmapmode.MNodeStyleController;
import org.freeplane.features.styles.AutomaticLayout;
import org.freeplane.features.styles.AutomaticLayoutController;
import org.freeplane.features.styles.IStyle;
import org.freeplane.features.styles.LogicalStyleController;
import org.freeplane.features.styles.LogicalStyleModel;
import org.freeplane.features.styles.MapStyle;
import org.freeplane.features.text.TextController;
import org.freeplane.features.ui.IMapViewChangeListener;
import org.freeplane.features.ui.IMapViewManager;
import com.jgoodies.forms.builder.DefaultFormBuilder;
import com.jgoodies.forms.factories.Borders;
import com.jgoodies.forms.layout.FormLayout;
public class StyleEditorPanel extends JPanel {
private static final NamedObject AUTOMATIC_LAYOUT_DISABLED = new NamedObject("automatic_layout_disabled");
private class BgColorChangeListener extends ChangeListener {
public BgColorChangeListener(final BooleanProperty mSet, final IPropertyControl mProperty) {
super(mSet, mProperty);
}
@Override
void applyValue(final boolean enabled, final NodeModel node, final PropertyChangeEvent evt) {
final MNodeStyleController styleController = (MNodeStyleController) Controller
.getCurrentModeController().getExtension(
NodeStyleController.class);
styleController.setBackgroundColor(node, enabled ? mNodeBackgroundColor.getColorValue() : null);
}
}
private class NodeShapeChangeListener extends ChangeListener {
public NodeShapeChangeListener(final BooleanProperty mSet, final IPropertyControl mProperty) {
super(mSet, mProperty);
}
@Override
void applyValue(final boolean enabled, final NodeModel node, final PropertyChangeEvent evt) {
final MNodeStyleController styleController = (MNodeStyleController) Controller
.getCurrentModeController().getExtension(
NodeStyleController.class);
styleController.setShape(node, enabled ? mNodeShape.getValue() : null);
}
}
private class ColorChangeListener extends ChangeListener {
public ColorChangeListener(final BooleanProperty mSet, final IPropertyControl mProperty) {
super(mSet, mProperty);
}
@Override
void applyValue(final boolean enabled, final NodeModel node, final PropertyChangeEvent evt) {
final MNodeStyleController styleController = (MNodeStyleController) Controller
.getCurrentModeController().getExtension(
NodeStyleController.class);
styleController.setColor(node, enabled ? mNodeColor.getColorValue() : null);
}
}
private class FontBoldChangeListener extends ChangeListener {
public FontBoldChangeListener(final BooleanProperty mSet, final IPropertyControl mProperty) {
super(mSet, mProperty);
}
@Override
void applyValue(final boolean enabled, final NodeModel node, final PropertyChangeEvent evt) {
final MNodeStyleController styleController = (MNodeStyleController) Controller
.getCurrentModeController().getExtension(
NodeStyleController.class);
styleController.setBold(node, enabled ? mNodeFontBold.getBooleanValue() : null);
}
}
private class FontItalicChangeListener extends ChangeListener {
public FontItalicChangeListener(final BooleanProperty mSet, final IPropertyControl mProperty) {
super(mSet, mProperty);
}
@Override
void applyValue(final boolean enabled, final NodeModel node, final PropertyChangeEvent evt) {
final MNodeStyleController styleController = (MNodeStyleController) Controller
.getCurrentModeController().getExtension(
NodeStyleController.class);
styleController.setItalic(node, enabled ? mNodeFontItalic.getBooleanValue() : null);
}
}
private class FontHyperlinkChangeListener extends ChangeListener {
public FontHyperlinkChangeListener(final BooleanProperty mSet, final IPropertyControl mProperty) {
super(mSet, mProperty);
}
@Override
void applyValue(final boolean enabled, final NodeModel node, final PropertyChangeEvent evt) {
final MLinkController styleController = (MLinkController) Controller
.getCurrentModeController().getExtension(
LinkController.class);
styleController.setFormatNodeAsHyperlink(node, enabled ? mNodeFontHyperlink.getBooleanValue() : null);
}
}
private class FontSizeChangeListener extends ChangeListener {
public FontSizeChangeListener(final BooleanProperty mSet, final IPropertyControl mProperty) {
super(mSet, mProperty);
}
@Override
void applyValue(final boolean enabled, final NodeModel node, final PropertyChangeEvent evt) {
final MNodeStyleController styleController = (MNodeStyleController) Controller
.getCurrentModeController().getExtension(
NodeStyleController.class);
try {
styleController.setFontSize(node, enabled ? Integer.valueOf(mNodeFontSize.getValue()) : null);
}
catch (NumberFormatException e) {
}
}
}
private class FontNameChangeListener extends ChangeListener {
public FontNameChangeListener(final BooleanProperty mSet, final IPropertyControl mProperty) {
super(mSet, mProperty);
}
@Override
void applyValue(final boolean enabled, final NodeModel node, final PropertyChangeEvent evt) {
final MNodeStyleController styleController = (MNodeStyleController) Controller
.getCurrentModeController().getExtension(
NodeStyleController.class);
styleController.setFontFamily(node, enabled ? mNodeFontName.getValue() : null);
}
}
private class EdgeColorChangeListener extends ChangeListener {
public EdgeColorChangeListener(final BooleanProperty mSet, final IPropertyControl mProperty) {
super(mSet, mProperty);
}
@Override
void applyValue(final boolean enabled, final NodeModel node, final PropertyChangeEvent evt) {
final MEdgeController edgeController = (MEdgeController) MEdgeController.getController();
edgeController.setColor(node, enabled ? mEdgeColor.getColorValue() : null);
}
}
private class EdgeStyleChangeListener extends ChangeListener {
public EdgeStyleChangeListener(final BooleanProperty mSet, final IPropertyControl mProperty) {
super(mSet, mProperty);
}
@Override
void applyValue(final boolean enabled, final NodeModel node,
final PropertyChangeEvent evt) {
final MEdgeController styleController = (MEdgeController) Controller
.getCurrentModeController().getExtension(
EdgeController.class);
styleController.setStyle(node, enabled ? EdgeStyle.getStyle(mEdgeStyle.getValue()) : null);
}
}
private class EdgeWidthChangeListener extends ChangeListener {
public EdgeWidthChangeListener(final BooleanProperty mSet, final IPropertyControl mProperty) {
super(mSet, mProperty);
}
@Override
void applyValue(final boolean enabled, final NodeModel node, final PropertyChangeEvent evt) {
final MEdgeController styleController = (MEdgeController) Controller
.getCurrentModeController().getExtension(
EdgeController.class);
styleController.setWidth(node, enabled ? Integer.parseInt(mEdgeWidth.getValue()): EdgeModel.DEFAULT_WIDTH);
}
}
private class MaxNodeWidthChangeListener extends ChangeListener {
public MaxNodeWidthChangeListener(final BooleanProperty mSet, final IPropertyControl mProperty) {
super(mSet, mProperty);
}
@Override
void applyValue(final boolean enabled, final NodeModel node, final PropertyChangeEvent evt) {
final MNodeStyleController styleController = (MNodeStyleController) Controller
.getCurrentModeController().getExtension(NodeStyleController.class);
styleController.setMaxNodeWidth(node, enabled ? Integer.parseInt(mMaxNodeWidth.getValue()): NodeSizeModel.NOT_SET);
}
}
private class MinNodeWidthChangeListener extends ChangeListener {
public MinNodeWidthChangeListener(final BooleanProperty mSet, final IPropertyControl mProperty) {
super(mSet, mProperty);
}
@Override
void applyValue(final boolean enabled, final NodeModel node, final PropertyChangeEvent evt) {
final MNodeStyleController styleController = (MNodeStyleController) Controller
.getCurrentModeController().getExtension(NodeStyleController.class);
styleController.setMinNodeWidth(node, enabled ? Integer.parseInt(mMinNodeWidth.getValue()): NodeSizeModel.NOT_SET);
}
}
private class CloudColorChangeListener extends ChangeListener {
public CloudColorChangeListener(final BooleanProperty mSet, final IPropertyControl mProperty) {
super(mSet, mProperty);
}
@Override
void applyValue(final boolean enabled, final NodeModel node,
final PropertyChangeEvent evt) {
final MCloudController styleController = (MCloudController) Controller
.getCurrentModeController().getExtension(
CloudController.class);
if (enabled) {
styleController.setColor(node, mCloudColor.getColorValue());
}
else {
styleController.setCloud(node, false);
}
}
}
private class CloudShapeChangeListener extends ChangeListener {
public CloudShapeChangeListener(final BooleanProperty mSet, final IPropertyControl mProperty) {
super(mSet, mProperty);
}
@Override
void applyValue(final boolean enabled, final NodeModel node,
final PropertyChangeEvent evt) {
final MCloudController styleController = (MCloudController) Controller
.getCurrentModeController().getExtension(
CloudController.class);
if (enabled) {
styleController.setShape(node, CloudModel.Shape.valueOf(mCloudShape.getValue()));
}
else {
styleController.setCloud(node, false);
}
}
}
private class NodeNumberingChangeListener extends ChangeListener {
public NodeNumberingChangeListener(final BooleanProperty mSet, final IPropertyControl mProperty) {
super(mSet, mProperty);
}
@Override
void applyValue(final boolean enabled, final NodeModel node, final PropertyChangeEvent evt) {
final MNodeStyleController styleController = (MNodeStyleController) Controller.getCurrentModeController()
.getExtension(NodeStyleController.class);
styleController.setNodeNumbering(node, enabled ? mNodeNumbering.getBooleanValue() : null);
}
}
private class NodeFormatChangeListener extends ChangeListener {
public NodeFormatChangeListener(final BooleanProperty mSet, final IPropertyControl mProperty) {
super(mSet, mProperty);
}
@Override
void applyValue(final boolean enabled, final NodeModel node, final PropertyChangeEvent evt) {
final MNodeStyleController styleController = (MNodeStyleController) Controller.getCurrentModeController()
.getExtension(NodeStyleController.class);
styleController.setNodeFormat(node, enabled ? mNodeFormat.getSelectedPattern() : null);
}
}
private class StyleChangeListener implements PropertyChangeListener{
public StyleChangeListener() {
}
public void propertyChange(PropertyChangeEvent evt) {
if(internalChange){
return;
}
BooleanProperty isSet = (BooleanProperty) evt.getSource();
final MLogicalStyleController styleController = (MLogicalStyleController) LogicalStyleController.getController();
if(isSet.getBooleanValue()){
styleController.setStyle((IStyle) uiFactory.getStyles().getSelectedItem());
}
else{
styleController.setStyle(null);
}
}
}
private abstract class ChangeListener implements PropertyChangeListener {
final private IPropertyControl mProperty;
final private BooleanProperty mSet;
public ChangeListener(final BooleanProperty mSet, final IPropertyControl mProperty) {
super();
this.mSet = mSet;
this.mProperty = mProperty;
}
abstract void applyValue(final boolean enabled, NodeModel node, PropertyChangeEvent evt);
public void propertyChange(final PropertyChangeEvent evt) {
if (internalChange) {
return;
}
final boolean enabled;
if (evt.getSource().equals(mSet)) {
enabled = mSet.getBooleanValue();
}
else {
assert evt.getSource().equals(mProperty);
enabled = true;
mSet.setValue(true);
}
final IMapSelection selection = Controller.getCurrentController().getSelection();
final Collection<NodeModel> nodes = selection.getSelection();
if (enabled )
internalChange = true;
for (final NodeModel node : nodes) {
applyValue(enabled, node, evt);
}
internalChange = false;
setStyle(selection.getSelected());
}
}
private static final String CLOUD_COLOR = "cloudcolor";
private static final String EDGE_COLOR = "edgecolor";
private static final String EDGE_STYLE = "edgestyle";
private static final String CLOUD_SHAPE = "cloudshape";
private static final String[] EDGE_STYLES = StyleEditorPanel.initializeEdgeStyles();
private static final String[] CLOUD_SHAPES = StyleEditorPanel.initializeCloudShapes();
private static final String EDGE_WIDTH = "edgewidth";
// private static final String ICON = "icon";
private static final String NODE_BACKGROUND_COLOR = "nodebackgroundcolor";
private static final String NODE_COLOR = "nodecolor";
private static final String NODE_FONT_BOLD = "nodefontbold";
private static final String NODE_FONT_ITALIC = "nodefontitalic";
private static final String NODE_FONT_HYPERLINK = "nodefonthyperlink";
private static final String NODE_FONT_NAME = "nodefontname";
private static final String NODE_FONT_SIZE = "nodefontsize";
private static final String NODE_NUMBERING = "nodenumbering";
private static final String NODE_SHAPE = "nodeshape";
private static final String NODE_TEXT_COLOR = "standardnodetextcolor";
private static final String NODE_FORMAT = "nodeformat";
/**
*
*/
private static final long serialVersionUID = 1L;
private static final String SET_RESOURCE = "set_property_text";
private static final String MAX_TEXT_WIDTH = "max_node_width";
private static final String MIN_NODE_WIDTH = "min_node_width";
private static String[] initializeEdgeStyles() {
final EdgeStyle[] enumConstants = EdgeStyle.class.getEnumConstants();
final String[] strings = new String[enumConstants.length-1];
for (int i = 0; i < enumConstants.length-1; i++) {
strings[i] = enumConstants[i].toString();
}
return strings;
}
private static String[] initializeCloudShapes() {
final CloudModel.Shape[] enumConstants = CloudModel.Shape.class.getEnumConstants();
final String[] strings = new String[enumConstants.length];
for (int i = 0; i < enumConstants.length; i++) {
strings[i] = enumConstants[i].toString();
}
return strings;
}
private boolean internalChange;
private ColorProperty mCloudColor;
private ComboProperty mCloudShape;
private List<IPropertyControl> mControls;
private ColorProperty mEdgeColor;
private ComboProperty mEdgeStyle;
private NumberProperty mEdgeWidth;
// private final ModeController mMindMapController;
private ColorProperty mNodeBackgroundColor;
private ColorProperty mNodeColor;
private BooleanProperty mNodeFontBold;
private BooleanProperty mNodeFontItalic;
private BooleanProperty mNodeFontHyperlink;
private FontProperty mNodeFontName;
private ComboProperty mNodeFontSize;
private BooleanProperty mNodeNumbering;
private ComboProperty mNodeShape;
private EditablePatternComboProperty mNodeFormat;
private NumberProperty mMaxNodeWidth;
private NumberProperty mMinNodeWidth;
private BooleanProperty mSetCloud;
private BooleanProperty mSetEdgeColor;
private BooleanProperty mSetEdgeStyle;
private BooleanProperty mSetEdgeWidth;
private BooleanProperty mSetNodeBackgroundColor;
private BooleanProperty mSetNodeColor;
private BooleanProperty mSetNodeFontBold;
private BooleanProperty mSetNodeFontItalic;
private BooleanProperty mSetNodeFontHyperlink;
private BooleanProperty mSetNodeFontName;
private BooleanProperty mSetNodeFontSize;
private BooleanProperty mSetNodeNumbering;
private BooleanProperty mSetNodeShape;
private BooleanProperty mSetNodeFormat;
private BooleanProperty mSetStyle;
private BooleanProperty mSetMaxNodeWidth;
private BooleanProperty mSetMinNodeWidth;
private final boolean addStyleBox;
private final MUIFactory uiFactory;
private final ModeController modeController;
private JButton mNodeStyleButton;
private JButton mMapStyleButton;
/**
* @throws HeadlessException
*/
public StyleEditorPanel(final ModeController modeController, final MUIFactory uiFactory,
final boolean addStyleBox) throws HeadlessException {
super();
this.modeController = modeController;
this.addStyleBox = addStyleBox;
this.uiFactory = uiFactory;
init();
}
private void addBgColorControl(final List<IPropertyControl> controls) {
mSetNodeBackgroundColor = new BooleanProperty(StyleEditorPanel.SET_RESOURCE);
controls.add(mSetNodeBackgroundColor);
mNodeBackgroundColor = new ColorProperty(StyleEditorPanel.NODE_BACKGROUND_COLOR, ResourceController
.getResourceController().getDefaultProperty(NODE_BACKGROUND_COLOR));
controls.add(mNodeBackgroundColor);
final BgColorChangeListener listener = new BgColorChangeListener(mSetNodeBackgroundColor, mNodeBackgroundColor);
mSetNodeBackgroundColor.addPropertyChangeListener(listener);
mNodeBackgroundColor.addPropertyChangeListener(listener);
mNodeBackgroundColor.fireOnMouseClick();
}
private void addFormatControl(final List<IPropertyControl> controls) {
mSetNodeFormat = new BooleanProperty(StyleEditorPanel.SET_RESOURCE);
controls.add(mSetNodeFormat);
mNodeFormat = new EditablePatternComboProperty(StyleEditorPanel.NODE_FORMAT,
PatternFormat.getIdentityPatternFormat(), FormatController.getController().getAllFormats());
controls.add(mNodeFormat);
final NodeFormatChangeListener listener = new NodeFormatChangeListener(mSetNodeFormat, mNodeFormat);
mSetNodeFormat.addPropertyChangeListener(listener);
mNodeFormat.addPropertyChangeListener(listener);
mNodeFormat.fireOnMouseClick();
}
private void addNodeNumberingControl(final List<IPropertyControl> controls) {
mSetNodeNumbering = new BooleanProperty(StyleEditorPanel.SET_RESOURCE);
controls.add(mSetNodeNumbering);
mNodeNumbering = new BooleanProperty(StyleEditorPanel.NODE_NUMBERING);
controls.add(mNodeNumbering);
final NodeNumberingChangeListener listener = new NodeNumberingChangeListener(mSetNodeNumbering, mNodeNumbering);
mSetNodeNumbering.addPropertyChangeListener(listener);
mNodeNumbering.addPropertyChangeListener(listener);
mNodeNumbering.fireOnMouseClick();
}
private void addCloudColorControl(final List<IPropertyControl> controls) {
mSetCloud = new BooleanProperty(StyleEditorPanel.SET_RESOURCE);
controls.add(mSetCloud);
mCloudColor = new ColorProperty(StyleEditorPanel.CLOUD_COLOR, ResourceController.getResourceController()
.getDefaultProperty(CloudController.RESOURCES_CLOUD_COLOR));
controls.add(mCloudColor);
final CloudColorChangeListener listener = new CloudColorChangeListener(mSetCloud, mCloudColor);
mSetCloud.addPropertyChangeListener(listener);
mCloudColor.addPropertyChangeListener(listener);
mCloudColor.fireOnMouseClick();
}
private void addColorControl(final List<IPropertyControl> controls) {
mSetNodeColor = new BooleanProperty(StyleEditorPanel.SET_RESOURCE);
controls.add(mSetNodeColor);
mNodeColor = new ColorProperty(StyleEditorPanel.NODE_COLOR, ResourceController.getResourceController()
.getDefaultProperty(NODE_TEXT_COLOR));
controls.add(mNodeColor);
final ColorChangeListener listener = new ColorChangeListener(mSetNodeColor, mNodeColor);
mSetNodeColor.addPropertyChangeListener(listener);
mNodeColor.addPropertyChangeListener(listener);
mNodeColor.fireOnMouseClick();
}
private void addEdgeColorControl(final List<IPropertyControl> controls) {
mSetEdgeColor = new BooleanProperty(StyleEditorPanel.SET_RESOURCE);
controls.add(mSetEdgeColor);
mEdgeColor = new ColorProperty(StyleEditorPanel.EDGE_COLOR, ColorUtils.colorToString(EdgeController.STANDARD_EDGE_COLOR));
controls.add(mEdgeColor);
final EdgeColorChangeListener listener = new EdgeColorChangeListener(mSetEdgeColor, mEdgeColor);
mSetEdgeColor.addPropertyChangeListener(listener);
mEdgeColor.addPropertyChangeListener(listener);
mEdgeColor.fireOnMouseClick();
}
private void addEdgeStyleControl(final List<IPropertyControl> controls) {
mSetEdgeStyle = new BooleanProperty(StyleEditorPanel.SET_RESOURCE);
controls.add(mSetEdgeStyle);
mEdgeStyle = new ComboProperty(StyleEditorPanel.EDGE_STYLE, EDGE_STYLES);
controls.add(mEdgeStyle);
final EdgeStyleChangeListener listener = new EdgeStyleChangeListener(mSetEdgeStyle, mEdgeStyle);
mSetEdgeStyle.addPropertyChangeListener(listener);
mEdgeStyle.addPropertyChangeListener(listener);
mEdgeStyle.fireOnMouseClick();
}
private void addCloudShapeControl(final List<IPropertyControl> controls) {
mCloudShape = new ComboProperty(StyleEditorPanel.CLOUD_SHAPE, CLOUD_SHAPES);
controls.add(mCloudShape);
final CloudShapeChangeListener listener = new CloudShapeChangeListener(mSetCloud, mCloudShape);
mSetCloud.addPropertyChangeListener(listener);
mCloudShape.addPropertyChangeListener(listener);
mCloudShape.fireOnMouseClick();
}
private void addEdgeWidthControl(final List<IPropertyControl> controls) {
mSetEdgeWidth = new BooleanProperty(StyleEditorPanel.SET_RESOURCE);
controls.add(mSetEdgeWidth);
mEdgeWidth = new NumberProperty(StyleEditorPanel.EDGE_WIDTH, 0, 100, 1);
controls.add(mEdgeWidth);
final EdgeWidthChangeListener listener = new EdgeWidthChangeListener(mSetEdgeWidth, mEdgeWidth);
mSetEdgeWidth.addPropertyChangeListener(listener);
mEdgeWidth.addPropertyChangeListener(listener);
mEdgeWidth.fireOnMouseClick();
}
private void addMaxNodeWidthControl(final List<IPropertyControl> controls) {
mSetMaxNodeWidth = new BooleanProperty(StyleEditorPanel.SET_RESOURCE);
controls.add(mSetMaxNodeWidth);
mMaxNodeWidth = new NumberProperty(StyleEditorPanel.MAX_TEXT_WIDTH, 1, Integer.MAX_VALUE, 1);
controls.add(mMaxNodeWidth);
final MaxNodeWidthChangeListener listener = new MaxNodeWidthChangeListener(mSetMaxNodeWidth, mMaxNodeWidth);
mSetMaxNodeWidth.addPropertyChangeListener(listener);
mMaxNodeWidth.addPropertyChangeListener(listener);
mMaxNodeWidth.fireOnMouseClick();
}
private void addMinNodeWidthControl(final List<IPropertyControl> controls) {
mSetMinNodeWidth = new BooleanProperty(StyleEditorPanel.SET_RESOURCE);
controls.add(mSetMinNodeWidth);
mMinNodeWidth = new NumberProperty(StyleEditorPanel.MIN_NODE_WIDTH, 1, Integer.MAX_VALUE, 1);
controls.add(mMinNodeWidth);
final MinNodeWidthChangeListener listener = new MinNodeWidthChangeListener(mSetMinNodeWidth, mMinNodeWidth);
mSetMinNodeWidth.addPropertyChangeListener(listener);
mMinNodeWidth.addPropertyChangeListener(listener);
mMinNodeWidth.fireOnMouseClick();
}
private void addFontBoldControl(final List<IPropertyControl> controls) {
mSetNodeFontBold = new BooleanProperty(StyleEditorPanel.SET_RESOURCE);
controls.add(mSetNodeFontBold);
mNodeFontBold = new BooleanProperty(StyleEditorPanel.NODE_FONT_BOLD);
controls.add(mNodeFontBold);
final FontBoldChangeListener listener = new FontBoldChangeListener(mSetNodeFontBold, mNodeFontBold);
mSetNodeFontBold.addPropertyChangeListener(listener);
mNodeFontBold.addPropertyChangeListener(listener);
mNodeFontBold.fireOnMouseClick();
}
private void addFontItalicControl(final List<IPropertyControl> controls) {
mSetNodeFontItalic = new BooleanProperty(StyleEditorPanel.SET_RESOURCE);
controls.add(mSetNodeFontItalic);
mNodeFontItalic = new BooleanProperty(StyleEditorPanel.NODE_FONT_ITALIC);
controls.add(mNodeFontItalic);
final FontItalicChangeListener listener = new FontItalicChangeListener(mSetNodeFontItalic, mNodeFontItalic);
mSetNodeFontItalic.addPropertyChangeListener(listener);
mNodeFontItalic.addPropertyChangeListener(listener);
mNodeFontItalic.fireOnMouseClick();
}
private void addFontHyperlinkControl(final List<IPropertyControl> controls) {
mSetNodeFontHyperlink = new BooleanProperty(StyleEditorPanel.SET_RESOURCE);
controls.add(mSetNodeFontHyperlink);
mNodeFontHyperlink = new BooleanProperty(StyleEditorPanel.NODE_FONT_HYPERLINK);
controls.add(mNodeFontHyperlink);
final FontHyperlinkChangeListener listener = new FontHyperlinkChangeListener(mSetNodeFontHyperlink, mNodeFontHyperlink);
mSetNodeFontHyperlink.addPropertyChangeListener(listener);
mNodeFontHyperlink.addPropertyChangeListener(listener);
mNodeFontHyperlink.fireOnMouseClick();
}
private void addFontNameControl(final List<IPropertyControl> controls) {
mSetNodeFontName = new BooleanProperty(StyleEditorPanel.SET_RESOURCE);
controls.add(mSetNodeFontName);
mNodeFontName = new FontProperty(StyleEditorPanel.NODE_FONT_NAME);
controls.add(mNodeFontName);
final FontNameChangeListener listener = new FontNameChangeListener(mSetNodeFontName, mNodeFontName);
mSetNodeFontName.addPropertyChangeListener(listener);
mNodeFontName.addPropertyChangeListener(listener);
mNodeFontName.fireOnMouseClick();
}
private void addFontSizeControl(final List<IPropertyControl> controls) {
mSetNodeFontSize = new BooleanProperty(StyleEditorPanel.SET_RESOURCE);
controls.add(mSetNodeFontSize);
final List<String> sizesVector = new ArrayList<String>(Arrays.asList(MUIFactory.FONT_SIZES));
mNodeFontSize = new ComboProperty(StyleEditorPanel.NODE_FONT_SIZE, sizesVector, sizesVector);
mNodeFontSize.setEditable(true);
controls.add(mNodeFontSize);
final FontSizeChangeListener listener = new FontSizeChangeListener(mSetNodeFontSize, mNodeFontSize);
mSetNodeFontSize.addPropertyChangeListener(listener);
mNodeFontSize.addPropertyChangeListener(listener);
mNodeFontSize.fireOnMouseClick();
}
private void addNodeShapeControl(final List<IPropertyControl> controls) {
mSetNodeShape = new BooleanProperty(StyleEditorPanel.SET_RESOURCE);
controls.add(mSetNodeShape);
mNodeShape = new ComboProperty(StyleEditorPanel.NODE_SHAPE, new String[] { "fork", "bubble", "as_parent",
"combined" });
controls.add(mNodeShape);
final NodeShapeChangeListener listener = new NodeShapeChangeListener(mSetNodeShape, mNodeShape);
mSetNodeShape.addPropertyChangeListener(listener);
mNodeShape.addPropertyChangeListener(listener);
mNodeShape.fireOnMouseClick();
}
private List<IPropertyControl> getControls() {
final List<IPropertyControl> controls = new ArrayList<IPropertyControl>();
controls.add(new SeparatorProperty("OptionPanel.separator.NodeColors"));
addColorControl(controls);
addBgColorControl(controls);
controls.add(new SeparatorProperty("OptionPanel.separator.NodeText"));
addFormatControl(controls);
addNodeNumberingControl(controls);
controls.add(new SeparatorProperty("OptionPanel.separator.NodeShape"));
addNodeShapeControl(controls);
addMinNodeWidthControl(controls);
addMaxNodeWidthControl(controls);
controls.add(new NextLineProperty());
controls.add(new SeparatorProperty("OptionPanel.separator.NodeFont"));
addFontNameControl(controls);
addFontSizeControl(controls);
addFontBoldControl(controls);
addFontItalicControl(controls);
addFontHyperlinkControl(controls);
controls.add(new NextLineProperty());
controls.add(new SeparatorProperty("OptionPanel.separator.EdgeControls"));
addEdgeWidthControl(controls);
addEdgeStyleControl(controls);
addEdgeColorControl(controls);
controls.add(new NextLineProperty());
controls.add(new SeparatorProperty("OptionPanel.separator.CloudControls"));
addCloudColorControl(controls);
controls.add(new NextLineProperty());
controls.add(new NextColumnProperty(2));
addCloudShapeControl(controls);
return controls;
}
/**
* Creates all controls and adds them to the frame.
* @param modeController
*/
private void init() {
final String form = "right:max(20dlu;p), 2dlu, p, 1dlu,right:max(20dlu;p), 4dlu, 80dlu, 7dlu";
final FormLayout rightLayout = new FormLayout(form, "");
final DefaultFormBuilder rightBuilder = new DefaultFormBuilder(rightLayout);
rightBuilder.setBorder(Borders.DLU2_BORDER);
rightBuilder.appendSeparator(TextUtils.getText("OptionPanel.separator.NodeStyle"));
if (addStyleBox) {
addAutomaticLayout(rightBuilder);
addStyleBox(rightBuilder);
}
mNodeStyleButton = addStyleButton(rightBuilder, "actual_node_styles", modeController.getAction(ManageNodeConditionalStylesAction.NAME));
if (addStyleBox) {
mMapStyleButton = addStyleButton(rightBuilder, "actual_map_styles", modeController.getAction(ManageMapConditionalStylesAction.NAME));
}
mControls = getControls();
for (final IPropertyControl control : mControls) {
control.layout(rightBuilder);
}
add(rightBuilder.getPanel(), BorderLayout.CENTER);
addListeners();
setFont(this, 10);
}
private JButton addStyleButton(DefaultFormBuilder rightBuilder, String label, AFreeplaneAction action) {
final JButton button = new JButton(){
private static final long serialVersionUID = 1L;
{
setUI(BasicButtonUI.createUI(this));
}
};
button.addActionListener(action);
button.setHorizontalAlignment(SwingConstants.LEFT);
final String labelText = TextUtils.getText(label);
UITools.addTitledBorder(button, labelText, 10);
rightBuilder.append(button, rightBuilder.getColumnCount());
rightBuilder.nextLine();
return button;
}
private void addStyleBox(final DefaultFormBuilder rightBuilder) {
mStyleBox = uiFactory.createStyleBox();
mSetStyle = new BooleanProperty(StyleEditorPanel.SET_RESOURCE);
final StyleChangeListener listener = new StyleChangeListener();
mSetStyle.addPropertyChangeListener(listener);
mSetStyle.layout(rightBuilder);
rightBuilder.append(new JLabel(TextUtils.getText("style")));
rightBuilder.append(mStyleBox);
rightBuilder.nextLine();
}
private JComboBox mAutomaticLayoutComboBox;
private JCheckBox mAutomaticEdgeColorCheckBox;
private Container mStyleBox;
private void addAutomaticLayout(final DefaultFormBuilder rightBuilder) {
{
if(mAutomaticLayoutComboBox == null){
NamedObject[] automaticLayoutTypes = NamedObject.fromEnum(AutomaticLayout.class);
mAutomaticLayoutComboBox = new JComboBox(automaticLayoutTypes);
DefaultComboBoxModel automaticLayoutComboBoxModel = (DefaultComboBoxModel) mAutomaticLayoutComboBox.getModel();
automaticLayoutComboBoxModel.addElement(AUTOMATIC_LAYOUT_DISABLED);
automaticLayoutComboBoxModel.setSelectedItem(AUTOMATIC_LAYOUT_DISABLED);
mAutomaticLayoutComboBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(internalChange)
return;
final ModeController modeController = Controller.getCurrentModeController();
AutomaticLayoutController al = modeController.getExtension(AutomaticLayoutController.class);
NamedObject selectedItem = (NamedObject)mAutomaticLayoutComboBox.getSelectedItem();
al.undoableDeactivateHook(Controller.getCurrentController().getMap().getRootNode());
if(!selectedItem.equals(AUTOMATIC_LAYOUT_DISABLED)){
al.undoableActivateHook(Controller.getCurrentController().getMap().getRootNode(), (AutomaticLayout) selectedItem.getObject());
}
}
});
}
final String label = TextUtils.getText("AutomaticLayoutAction.text");
rightBuilder.append(new JLabel(label), 5);
rightBuilder.append(mAutomaticLayoutComboBox);
rightBuilder.nextLine();
}
{
if(mAutomaticEdgeColorCheckBox == null){
mAutomaticEdgeColorCheckBox = new JCheckBox();
mAutomaticEdgeColorCheckBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
final ModeController modeController = Controller.getCurrentModeController();
AutomaticEdgeColorHook al = (AutomaticEdgeColorHook) modeController.getExtension(AutomaticEdgeColorHook.class);
al.undoableToggleHook(Controller.getCurrentController().getMap().getRootNode());
}
});
}
final String label = TextUtils.getText("AutomaticEdgeColorHookAction.text");
rightBuilder.append(new JLabel(label), 5);
rightBuilder.append(mAutomaticEdgeColorCheckBox);
rightBuilder.nextLine();
}
}
private void setFont(Container c, float size) {
c.setFont(c.getFont().deriveFont(size));
for(int i = 0; i < c.getComponentCount(); i++){
setFont((Container) c.getComponent(i), size);
}
}
public void setStyle( final NodeModel node) {
if (internalChange) {
return;
}
internalChange = true;
try {
final LogicalStyleController logicalStyleController = LogicalStyleController.getController();
if(addStyleBox){
final boolean isStyleSet = LogicalStyleModel.getStyle(node) != null;
mSetStyle.setValue(isStyleSet);
setStyleList(mMapStyleButton, logicalStyleController.getMapStyleNames(node, "\n"));
}
setStyleList(mNodeStyleButton, logicalStyleController.getNodeStyleNames(node, "\n"));
final NodeStyleController styleController = NodeStyleController.getController();
{
final Color nodeColor = NodeStyleModel.getColor(node);
final Color viewNodeColor = styleController.getColor(node);
mSetNodeColor.setValue(nodeColor != null);
mNodeColor.setColorValue(viewNodeColor);
}
{
final Color color = NodeStyleModel.getBackgroundColor(node);
final Color viewColor = styleController.getBackgroundColor(node);
mSetNodeBackgroundColor.setValue(color != null);
mNodeBackgroundColor.setColorValue(viewColor != null ? viewColor : Controller.getCurrentController()
.getMapViewManager().getBackgroundColor(node));
}
{
final String shape = NodeStyleModel.getShape(node);
final String viewShape = styleController.getShape(node);
mSetNodeShape.setValue(shape != null);
mNodeShape.setValue(viewShape);
}
final NodeSizeModel nodeSizeModel = NodeSizeModel.getModel(node);
{
final int width = nodeSizeModel != null ? nodeSizeModel.getMaxNodeWidth() : NodeSizeModel.NOT_SET;
final int viewWidth = styleController.getMaxWidth(node);
mSetMaxNodeWidth.setValue(width != NodeSizeModel.NOT_SET);
mMaxNodeWidth.setValue(Integer.toString(viewWidth));
}
{
final int width = nodeSizeModel != null ? nodeSizeModel.getMinNodeWidth() : NodeSizeModel.NOT_SET;
final int viewWidth = styleController.getMinWidth(node);
mSetMinNodeWidth.setValue(width != NodeSizeModel.NOT_SET);
mMinNodeWidth.setValue(Integer.toString(viewWidth));
}
final EdgeController edgeController = EdgeController.getController();
final EdgeModel edgeModel = EdgeModel.getModel(node);
{
final Color edgeColor = edgeModel != null ? edgeModel.getColor() : null;
final Color viewColor = edgeController.getColor(node);
mSetEdgeColor.setValue(edgeColor != null);
mEdgeColor.setColorValue(viewColor);
}
{
final EdgeStyle style = edgeModel != null ? edgeModel.getStyle() : null;
final EdgeStyle viewStyle = edgeController.getStyle(node);
mSetEdgeStyle.setValue(style != null);
mEdgeStyle.setValue(viewStyle.toString());
}
{
final int width = edgeModel != null ? edgeModel.getWidth() : EdgeModel.DEFAULT_WIDTH;
final int viewWidth = edgeController.getWidth(node);
mSetEdgeWidth.setValue(width != EdgeModel.DEFAULT_WIDTH);
mEdgeWidth.setValue(Integer.toString(viewWidth));
}
{
final CloudController cloudController = CloudController.getController();
final CloudModel cloudModel = CloudModel.getModel(node);
final Color viewCloudColor = cloudController.getColor(node);
mSetCloud.setValue(cloudModel != null);
mCloudColor.setColorValue(viewCloudColor);
final CloudModel.Shape viewCloudShape = cloudController.getShape(node);
mCloudShape.setValue(viewCloudShape != null ? viewCloudShape.toString() : CloudModel.Shape.ARC.toString());
}
{
final String fontFamilyName = NodeStyleModel.getFontFamilyName(node);
final String viewFontFamilyName = styleController.getFontFamilyName(node);
mSetNodeFontName.setValue(fontFamilyName != null);
mNodeFontName.setValue(viewFontFamilyName);
}
{
final Integer fontSize = NodeStyleModel.getFontSize(node);
final Integer viewfontSize = styleController.getFontSize(node);
mSetNodeFontSize.setValue(fontSize != null);
mNodeFontSize.setValue(viewfontSize.toString());
}
{
final Boolean bold = NodeStyleModel.isBold(node);
final Boolean viewbold = styleController.isBold(node);
mSetNodeFontBold.setValue(bold != null);
mNodeFontBold.setValue(viewbold);
}
{
final Boolean italic = NodeStyleModel.isItalic(node);
final Boolean viewitalic = styleController.isItalic(node);
mSetNodeFontItalic.setValue(italic != null);
mNodeFontItalic.setValue(viewitalic);
}
{
final Boolean hyperlink = NodeLinks.formatNodeAsHyperlink(node);
final Boolean viewhyperlink = LinkController.getController().formatNodeAsHyperlink(node);
mSetNodeFontHyperlink.setValue(hyperlink != null);
mNodeFontHyperlink.setValue(viewhyperlink);
}
{
final Boolean nodeNumbering = NodeStyleModel.getNodeNumbering(node);
final Boolean viewNodeNumbering = styleController.getNodeNumbering(node);
mSetNodeNumbering.setValue(nodeNumbering != null);
mNodeNumbering.setValue(viewNodeNumbering);
}
{
String nodeFormat = NodeStyleModel.getNodeFormat(node);
String viewNodeFormat = TextController.getController().getNodeFormat(node);
mSetNodeFormat.setValue(nodeFormat != null);
if (viewNodeFormat == null && node.getUserObject() instanceof IFormattedObject)
viewNodeFormat = ((IFormattedObject)node.getUserObject()).getPattern();
mNodeFormat.setValue(viewNodeFormat);
}
if(mAutomaticLayoutComboBox != null){
final ModeController modeController = Controller.getCurrentModeController();
AutomaticLayoutController al = modeController.getExtension(AutomaticLayoutController.class);
IExtension extension = al.getExtension(node);
if(extension == null)
mAutomaticLayoutComboBox.setSelectedItem(AUTOMATIC_LAYOUT_DISABLED);
else
mAutomaticLayoutComboBox.setSelectedIndex(((AutomaticLayout)extension).ordinal());
}
if(mAutomaticEdgeColorCheckBox != null){
final ModeController modeController = Controller.getCurrentModeController();
AutomaticEdgeColorHook al = (AutomaticEdgeColorHook) modeController.getExtension(AutomaticEdgeColorHook.class);
mAutomaticEdgeColorCheckBox.setSelected(al.isActive(node));
}
}
finally {
internalChange = false;
}
}
private void setStyleList(JButton btn, String styles) {
if("".equals(styles)){
btn.setToolTipText(null);
btn.setText(" ");
return;
}
btn.setToolTipText(HtmlUtils.plainToHTML(styles));
final String text = styles.replaceAll("\n", ", ");
btn.setText(text);
}
private void addListeners() {
final Controller controller = Controller.getCurrentController();
final ModeController modeController = Controller.getCurrentModeController();
final MapController mapController = modeController.getMapController();
mapController.addNodeSelectionListener(new INodeSelectionListener() {
public void onSelect(final NodeModel node) {
final IMapSelection selection = controller.getSelection();
if (selection == null) {
return;
}
if (selection.size() == 1) {
setStyle(node);
}
}
public void onDeselect(final NodeModel node) {
}
});
mapController.addNodeChangeListener(new INodeChangeListener() {
public void nodeChanged(final NodeChangeEvent event) {
final IMapSelection selection = controller.getSelection();
if (selection == null) {
return;
}
final NodeModel node = event.getNode();
if (selection.getSelected().equals(node)) {
setStyle(node);
}
}
});
mapController.addMapChangeListener(new AMapChangeListenerAdapter() {
@Override
public void mapChanged(MapChangeEvent event) {
if(! MapStyle.MAP_STYLES.equals(event.getProperty()))
return;
final IMapSelection selection = controller.getSelection();
if (selection == null) {
return;
}
final NodeModel node = selection.getSelected();
setStyle(node);
}
public void onSavedAs(MapModel map) {
}
public void onSaved(MapModel map) {
}
});
final IMapViewManager mapViewManager = controller.getMapViewManager();
mapViewManager.addMapViewChangeListener(new IMapViewChangeListener() {
public void beforeViewChange(final Component oldView, final Component newView) {
}
public void afterViewCreated(final Component mapView) {
}
public void afterViewClose(final Component oldView) {
}
public void afterViewChange(final Component oldView, final Component newView) {
final Container panel = (Container) getComponent(0);
for (int i = 0; i < panel.getComponentCount(); i++) {
panel.getComponent(i).setEnabled(newView != null);
}
}
});
}
}