/*FreeMind - A Program for creating and viewing Mindmaps *Copyright (C) 2000-2006 Joerg Mueller, Daniel Polansky, Christian Foltin, Dimitri Polivaev and others. * *See COPYING for Details * *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, write to the Free Software *Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* * Created on 10.12.2005 * Copyright (C) 2005 Dimitri Polivaev */ package freemind.modes.mindmapmode.attributeactors; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.LinkedList; import java.util.ListIterator; import java.util.NoSuchElementException; import javax.swing.AbstractListModel; import javax.swing.Box; import javax.swing.ButtonGroup; import javax.swing.ComboBoxModel; import javax.swing.DefaultComboBoxModel; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JRadioButton; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import javax.swing.border.MatteBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; import freemind.controller.MapModuleManager.MapModuleChangeObserver; import freemind.main.Resources; import freemind.main.Tools; import freemind.modes.MindMap; import freemind.modes.MindMapNode; import freemind.modes.Mode; import freemind.modes.attributes.Attribute; import freemind.modes.attributes.AttributeRegistry; import freemind.modes.attributes.AttributeRegistryElement; import freemind.modes.attributes.NodeAttributeTableModel; import freemind.modes.mindmapmode.MindMapMode; import freemind.view.MapModule; import freemind.view.mindmapview.MapView; import freemind.view.mindmapview.NodeView; public class AssignAttributeDialog extends JDialog implements AttributesListener, MapModuleChangeObserver { private static class ClonedComboBoxModel extends AbstractListModel implements ComboBoxModel { private AbstractListModel sharedListModel; private Object selectedItem; private ListDataEvent ev = null; public ClonedComboBoxModel(ComboBoxModel sharedListModel) { super(); this.sharedListModel = (AbstractListModel) sharedListModel; } public void addListDataListener(ListDataListener l) { super.addListDataListener(l); sharedListModel.addListDataListener(l); } public Object getElementAt(int index) { return sharedListModel.getElementAt(index); } public int getSize() { return sharedListModel.getSize(); } public void removeListDataListener(ListDataListener l) { super.removeListDataListener(l); sharedListModel.removeListDataListener(l); } public void setSelectedItem(Object anItem) { selectedItem = anItem; fireContentsChanged(this, -1, -1); } private ListDataEvent getContentChangedEvent() { if (ev == null) { ev = new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, -1, -1); } return ev; } public Object getSelectedItem() { return selectedItem; } } private abstract class IteratingAction implements ActionListener { public void actionPerformed(ActionEvent e) { try { if (selectedBtn.getModel().isSelected()) { LinkedList selecteds = mapView.getSelecteds(); ListIterator iterator = selecteds.listIterator(); while (iterator.hasNext()) { NodeView selectedNodeView = (NodeView) iterator.next(); performAction(selectedNodeView); } return; } final NodeView nodeView = mapView.getRoot(); iterate(nodeView); } catch (NullPointerException ex) { } } private void iterate(final NodeView nodeView) { int n = nodeView.getComponentCount(); if (nodeView.isVisible()) { performAction(nodeView); } for (int i = 0; i < n; i++) { Component component = nodeView.getComponent(i); if (component instanceof NodeView) { iterate((NodeView) component); } } } private void performAction(NodeView selectedNodeView) { if (!selectedNodeView.isRoot() || !skipRootBtn.isSelected()) performAction(selectedNodeView.getModel()); } abstract protected void performAction(MindMapNode model); protected void showEmptyStringErrorMessage() { JOptionPane.showMessageDialog( AssignAttributeDialog.this, Resources.getInstance().getResourceString( "attributes_adding_empty_attribute_error"), Resources.getInstance().getResourceString("error"), JOptionPane.ERROR_MESSAGE); } } private class AddAction extends IteratingAction { private String name; private String value; protected void performAction(MindMapNode model) { model.createAttributeTableModel(); NodeAttributeTableModel attributes = model.getAttributes(); attributes.getAttributeController().performInsertRow(attributes, attributes.getRowCount(), name, value); } public void actionPerformed(ActionEvent e) { if (attributeNames.getSelectedItem() == null) { showEmptyStringErrorMessage(); return; } name = attributeNames.getSelectedItem().toString(); if (name.equals("")) { showEmptyStringErrorMessage(); return; } Object valueSelectedItem = attributeValues.getSelectedItem(); value = valueSelectedItem != null ? valueSelectedItem.toString() : ""; super.actionPerformed(e); if (valueSelectedItem == null) { selectedAttributeChanged(name, attributeValues); } } } private class DeleteAttributeAction extends IteratingAction { private String name; public void actionPerformed(ActionEvent e) { final Object selectedItem = attributeNames.getSelectedItem(); if (selectedItem == null) { showEmptyStringErrorMessage(); return; } name = selectedItem.toString(); if (name.equals("")) { showEmptyStringErrorMessage(); return; } super.actionPerformed(e); } protected void performAction(MindMapNode model) { NodeAttributeTableModel attributes = model.getAttributes(); for (int i = attributes.getRowCount() - 1; i >= 0; i--) { if (attributes.getAttribute(i).getName().equals(name)) { attributes.getAttributeController().performRemoveRow( attributes, i); } } } } private class DeleteValueAction extends IteratingAction { private String name; private String value; public void actionPerformed(ActionEvent e) { if (attributeNames.getSelectedItem() == null) { showEmptyStringErrorMessage(); return; } name = attributeNames.getSelectedItem().toString(); if (name.equals("")) { showEmptyStringErrorMessage(); return; } Object valueSelectedItem = attributeValues.getSelectedItem(); value = valueSelectedItem != null ? valueSelectedItem.toString() : ""; super.actionPerformed(e); } protected void performAction(MindMapNode model) { NodeAttributeTableModel attributes = model.getAttributes(); for (int i = attributes.getRowCount() - 1; i >= 0; i--) { Attribute attribute = attributes.getAttribute(i); if (attribute.getName().equals(name) && attribute.getValue().equals(value)) { attributes.getAttributeController().performRemoveRow( attributes, i); } } } } private class ReplaceValueAction extends IteratingAction { private String name; private String value; private String replacingName; private String replacingValue; public void actionPerformed(ActionEvent e) { if (attributeNames.getSelectedItem() == null) { showEmptyStringErrorMessage(); return; } if (replacingAttributeNames.getSelectedItem() == null) { showEmptyStringErrorMessage(); return; } name = attributeNames.getSelectedItem().toString(); if (name.equals("")) { showEmptyStringErrorMessage(); return; } replacingName = replacingAttributeNames.getSelectedItem() .toString(); if (replacingName.equals("")) { showEmptyStringErrorMessage(); return; } Object valueSelectedItem = attributeValues.getSelectedItem(); value = valueSelectedItem != null ? valueSelectedItem.toString() : ""; Object replacingValueSelectedItem = replacingAttributeValues .getSelectedItem(); replacingValue = replacingValueSelectedItem != null ? replacingValueSelectedItem .toString() : ""; super.actionPerformed(e); } protected void performAction(MindMapNode model) { NodeAttributeTableModel attributes = model.getAttributes(); for (int i = attributes.getRowCount() - 1; i >= 0; i--) { Attribute attribute = attributes.getAttribute(i); if (attribute.getName().equals(name) && attribute.getValue().equals(value)) { attributes.getAttributeController().performRemoveRow( attributes, i); attributes.insertRow(i, replacingName, replacingValue); } } } } private static final Dimension maxButtonDimension = new Dimension(1000, 1000); private MapView mapView; private JComboBox attributeNames; private JComboBox attributeValues; private JComboBox replacingAttributeNames; private JComboBox replacingAttributeValues; private JRadioButton selectedBtn; private JRadioButton visibleBtn; private JCheckBox skipRootBtn; public AssignAttributeDialog(MapView mapView) { super(JOptionPane.getFrameForComponent(mapView), Tools .removeMnemonic(Resources.getInstance().getResourceString( "attributes_assign_dialog")), false); final Border actionBorder = new MatteBorder(2, 2, 2, 2, Color.BLACK); final Border emptyBorder = new EmptyBorder(5, 5, 5, 5); final Border btnBorder = new EmptyBorder(2, 2, 2, 2); selectedBtn = new JRadioButton(); Tools.setLabelAndMnemonic(selectedBtn, Resources.getInstance() .getResourceString("attributes_for_selected")); selectedBtn.setSelected(true); visibleBtn = new JRadioButton(); Tools.setLabelAndMnemonic(visibleBtn, Resources.getInstance() .getResourceString("attributes_for_visible")); final ButtonGroup group = new ButtonGroup(); group.add(selectedBtn); group.add(visibleBtn); skipRootBtn = new JCheckBox(); Tools.setLabelAndMnemonic(skipRootBtn, Resources.getInstance() .getResourceString("attributes_skip_root")); skipRootBtn.setSelected(true); final Box selectionBox = Box.createHorizontalBox(); selectionBox.setBorder(emptyBorder); selectionBox.add(Box.createHorizontalGlue()); selectionBox.add(selectedBtn); selectionBox.add(Box.createHorizontalGlue()); selectionBox.add(visibleBtn); selectionBox.add(Box.createHorizontalGlue()); selectionBox.add(skipRootBtn); selectionBox.add(Box.createHorizontalGlue()); getContentPane().add(selectionBox, BorderLayout.NORTH); final JButton addBtn = new JButton(); Tools.setLabelAndMnemonic(addBtn, Resources.getInstance() .getResourceString("filter_add")); addBtn.addActionListener(new AddAction()); addBtn.setMaximumSize(maxButtonDimension); JButton deleteAttributeBtn = new JButton(); Tools.setLabelAndMnemonic(deleteAttributeBtn, Resources.getInstance() .getResourceString("attribute_delete")); deleteAttributeBtn.addActionListener(new DeleteAttributeAction()); deleteAttributeBtn.setMaximumSize(maxButtonDimension); JButton deleteAttributeValueBtn = new JButton(); Tools.setLabelAndMnemonic(deleteAttributeValueBtn, Resources .getInstance().getResourceString("attribute_delete_value")); deleteAttributeValueBtn.addActionListener(new DeleteValueAction()); deleteAttributeValueBtn.setMaximumSize(maxButtonDimension); JButton replaceBtn = new JButton(); Tools.setLabelAndMnemonic(replaceBtn, Resources.getInstance() .getResourceString("attribute_replace")); replaceBtn.addActionListener(new ReplaceValueAction()); replaceBtn.setMaximumSize(maxButtonDimension); Tools.addEscapeActionToDialog(this); final String pattern = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; final JLabel patternLabel = new JLabel(pattern); final Dimension comboBoxMaximumSize = patternLabel.getPreferredSize(); comboBoxMaximumSize.width += 4; comboBoxMaximumSize.height += 4; attributeNames = new JComboBox(); attributeNames.setMaximumSize(comboBoxMaximumSize); attributeNames.setPreferredSize(comboBoxMaximumSize); attributeNames.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { selectedAttributeChanged(e.getItem(), attributeValues); } }); attributeValues = new JComboBox(); attributeValues.setMaximumSize(comboBoxMaximumSize); attributeValues.setPreferredSize(comboBoxMaximumSize); replacingAttributeNames = new JComboBox(); replacingAttributeNames.setMaximumSize(comboBoxMaximumSize); replacingAttributeNames.setPreferredSize(comboBoxMaximumSize); replacingAttributeNames.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { selectedAttributeChanged(e.getItem(), replacingAttributeValues); } }); replacingAttributeValues = new JComboBox(); replacingAttributeValues.setMaximumSize(comboBoxMaximumSize); replacingAttributeValues.setPreferredSize(comboBoxMaximumSize); final Box addDeleteBtnBox = Box.createVerticalBox(); addDeleteBtnBox.setBorder(btnBorder); addDeleteBtnBox.add(Box.createVerticalGlue()); addDeleteBtnBox.add(addBtn); addDeleteBtnBox.add(deleteAttributeBtn); addDeleteBtnBox.add(deleteAttributeValueBtn); addDeleteBtnBox.add(Box.createVerticalGlue()); final Box addDeleteBox = Box.createHorizontalBox(); addDeleteBox.setBorder(actionBorder); addDeleteBox.add(Box.createHorizontalGlue()); addDeleteBox.add(addDeleteBtnBox); addDeleteBox.add(Box.createHorizontalStrut(5)); addDeleteBox.add(attributeNames); addDeleteBox.add(Box.createHorizontalStrut(5)); addDeleteBox.add(attributeValues); addDeleteBox.add(Box.createHorizontalStrut(5)); final Box outerReplaceBox = Box.createVerticalBox(); outerReplaceBox.setBorder(actionBorder); final Box replaceBox = Box.createHorizontalBox(); replaceBox.setBorder(btnBorder); replaceBox.add(Box.createHorizontalGlue()); replaceBox.add(replaceBtn); replaceBox.add(Box.createHorizontalStrut(5)); replaceBox.add(replacingAttributeNames); replaceBox.add(Box.createHorizontalStrut(5)); replaceBox.add(replacingAttributeValues); replaceBox.add(Box.createHorizontalStrut(5)); outerReplaceBox.add(Box.createVerticalGlue()); outerReplaceBox.add(replaceBox); outerReplaceBox.add(Box.createVerticalGlue()); final Box actionBox = Box.createVerticalBox(); actionBox.add(Box.createVerticalGlue()); actionBox.add(addDeleteBox); actionBox.add(Box.createVerticalStrut(5)); actionBox.add(outerReplaceBox); actionBox.add(Box.createVerticalGlue()); getContentPane().add(actionBox, BorderLayout.CENTER); final JButton closeBtn = new JButton(); Tools.setLabelAndMnemonic(closeBtn, Resources.getInstance() .getResourceString("close")); closeBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { dispose(); } }); final Box bottomBox = Box.createHorizontalBox(); bottomBox.setBorder(emptyBorder); bottomBox.add(Box.createHorizontalGlue()); bottomBox.add(closeBtn); bottomBox.add(Box.createHorizontalGlue()); getContentPane().add(bottomBox, BorderLayout.SOUTH); pack(); comboBoxMaximumSize.width = 1000; attributeNames.setMaximumSize(comboBoxMaximumSize); attributeValues.setMaximumSize(comboBoxMaximumSize); replacingAttributeNames.setMaximumSize(comboBoxMaximumSize); replacingAttributeValues.setMaximumSize(comboBoxMaximumSize); mapChanged(mapView); mapView.getController().getMapModuleManager().addListener(this); } public void mapChanged(MapView currentMapView) { if (mapView != null) { mapView.getModel().getRegistry().getAttributes() .removeAttributesListener(this); } mapView = currentMapView; MindMap map = currentMapView.getModel(); AttributeRegistry attributes = map.getRegistry().getAttributes(); attributes.addAttributesListener(this); attributesChanged(); } private void selectedAttributeChanged(Object selectedAttributeName, JComboBox values) { AttributeRegistry attributes = mapView.getModel().getRegistry() .getAttributes(); try { AttributeRegistryElement element = attributes .getElement(selectedAttributeName.toString()); ComboBoxModel selectedValues = element.getValues(); values.setModel(new ClonedComboBoxModel(selectedValues)); try { Object firstValue = selectedValues.getElementAt(0); values.setSelectedItem(firstValue); } catch (ArrayIndexOutOfBoundsException ex) { } values.setEditable(!element.isRestricted()); } catch (NoSuchElementException ex) { values.setEditable(!selectedAttributeName.toString().equals("")); } } public void attributesChanged(ChangeEvent e) { attributesChanged(); } private void attributesChanged() { AttributeRegistry attributes = mapView.getModel().getRegistry() .getAttributes(); ComboBoxModel names = attributes.getComboBoxModel(); attributeNames.setModel(new ClonedComboBoxModel(names)); attributeNames.setEditable(!attributes.isRestricted()); replacingAttributeNames.setModel(new ClonedComboBoxModel(names)); replacingAttributeNames.setEditable(!attributes.isRestricted()); if (attributes.size() > 0) { Object first = names.getElementAt(0); attributeNames.setSelectedItem(first); replacingAttributeNames.setSelectedItem(first); selectedAttributeChanged(attributeNames.getSelectedItem(), attributeValues); selectedAttributeChanged(replacingAttributeNames.getSelectedItem(), replacingAttributeValues); } else { attributeValues.setModel(new DefaultComboBoxModel()); attributeValues.setEditable(false); replacingAttributeValues.setModel(new DefaultComboBoxModel()); replacingAttributeValues.setEditable(false); } } public boolean isMapModuleChangeAllowed(MapModule oldMapModule, Mode oldMode, MapModule newMapModule, Mode newMode) { return !isVisible() || newMode instanceof MindMapMode; } public void beforeMapModuleChange(MapModule oldMapModule, Mode oldMode, MapModule newMapModule, Mode newMode) { } public void afterMapModuleChange(MapModule oldMapModule, Mode oldMode, MapModule newMapModule, Mode newMode) { if (newMapModule != null) mapChanged(newMapModule.getView()); } public void numberOfOpenMapInformation(int number, int pIndex) { } public void afterMapClose(MapModule pOldMapModule, Mode pOldMode) { } }