/*
* 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.core.resources.components;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Properties;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.tree.DefaultMutableTreeNode;
import org.apache.commons.lang.StringUtils;
import org.freeplane.core.resources.ResourceController;
import org.freeplane.core.resources.components.IValidator.ValidationResult;
import org.freeplane.core.ui.MenuBuilder;
import org.freeplane.core.ui.components.UITools;
import org.freeplane.core.util.LogUtils;
import org.freeplane.core.util.TextUtils;
import org.freeplane.features.mode.Controller;
import com.jgoodies.forms.builder.DefaultFormBuilder;
import com.jgoodies.forms.factories.ButtonBarFactory;
import com.jgoodies.forms.layout.FormLayout;
public class OptionPanel {
final private class ChangeTabAction implements ActionListener {
final private CardLayout cardLayout;
final private JPanel centralPanel;
final private String tabName;
private ChangeTabAction(final CardLayout cardLayout, final JPanel centralPanel, final String tabName) {
super();
this.cardLayout = cardLayout;
this.centralPanel = centralPanel;
this.tabName = tabName;
}
public void actionPerformed(final ActionEvent arg0) {
cardLayout.show(centralPanel, tabName);
for (final JButton button : tabButtonMap.values()) {
button.setForeground(null);
}
getTabButton(tabName).setForeground(OptionPanel.MARKED_BUTTON_COLOR);
selectedPanel = tabName;
}
}
public interface IOptionPanelFeedback {
void writeProperties(Properties props);
}
private static final Color MARKED_BUTTON_COLOR = Color.BLUE;
static final String PREFERENCE_STORAGE_PROPERTY = "OptionPanel_Window_Properties";
private Vector<IPropertyControl> controls;
final private IOptionPanelFeedback feedback;
private String selectedPanel;
final private HashMap<String, ChangeTabAction> tabActionMap = new HashMap<String, ChangeTabAction>();
final private HashMap<String, JButton> tabButtonMap = new HashMap<String, JButton>();
final private JDialog topDialog;
/**
* @throws IOException
*/
public OptionPanel(final JDialog d, final IOptionPanelFeedback feedback) {
super();
topDialog = d;
this.feedback = feedback;
new OptionPanelBuilder();
}
public void buildPanel(final DefaultMutableTreeNode controlsTree) {
final FormLayout leftLayout = new FormLayout("max(80dlu;p):grow", "");
final DefaultFormBuilder leftBuilder = new DefaultFormBuilder(leftLayout);
final CardLayout cardLayout = new VariableSizeCardLayout();
final JPanel rightStack = new JPanel(cardLayout);
FormLayout rightLayout = null;
DefaultFormBuilder rightBuilder = null;
String lastTabName = null;
initControls(controlsTree);
final Iterator<IPropertyControl> iterator = controls.iterator();
//MaG:
Controller.getCurrentController().getOptionPanelController().setCurrentPropertyControls(controls);
while (iterator.hasNext()) {
final IPropertyControl control = iterator.next();
if (control instanceof TabProperty) {
final TabProperty newTab = (TabProperty) control;
if (rightBuilder != null) {
rightStack.add(rightBuilder.getPanel(), lastTabName);
}
rightLayout = new FormLayout(newTab.getDescription(), "");
rightBuilder = new DefaultFormBuilder(rightLayout);
rightBuilder.setDefaultDialogBorder();
lastTabName = newTab.getLabel();
final JButton tabButton = new JButton(TextUtils.getOptionalText(lastTabName));
final ChangeTabAction changeTabAction = new ChangeTabAction(cardLayout, rightStack, lastTabName);
tabButton.addActionListener(changeTabAction);
registerTabButton(tabButton, lastTabName, changeTabAction);
leftBuilder.append(tabButton);
}
else {
control.layout(rightBuilder);
}
}
rightStack.add(rightBuilder.getPanel(), lastTabName);
if (selectedPanel != null && tabActionMap.containsKey(selectedPanel)) {
(tabActionMap.get(selectedPanel)).actionPerformed(null);
}
final JScrollPane rightComponent = new JScrollPane(rightStack);
UITools.setScrollbarIncrement(rightComponent);
final JSplitPane centralPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftBuilder.getPanel(),
rightComponent);
topDialog.getContentPane().add(centralPanel, BorderLayout.CENTER);
final JButton cancelButton = new JButton();
MenuBuilder.setLabelAndMnemonic(cancelButton, TextUtils.getRawText("cancel"));
cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent arg0) {
closeWindow();
}
});
final JButton okButton = new JButton();
MenuBuilder.setLabelAndMnemonic(okButton, TextUtils.getRawText("ok"));
okButton.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent arg0) {
if (validate()) {
closeWindow();
feedback.writeProperties(getOptionProperties());
}
}
});
topDialog.getRootPane().setDefaultButton(okButton);
topDialog.getContentPane().add(ButtonBarFactory.buildOKCancelBar(cancelButton, okButton), BorderLayout.SOUTH);
}
private boolean validate() {
final Properties properties = getOptionProperties();
final ValidationResult result = new ValidationResult();
for (IValidator validator : Controller.getCurrentController().getOptionValidators()) {
result.add(validator.validate(properties));
}
if (!result.isValid()) {
UITools.errorMessage(formatErrors("OptionPanel.validation_error", result.getErrors()));
LogUtils.severe(result.toString());
}
else if (result.hasWarnings()) {
UITools.informationMessage(formatErrors("OptionPanel.validation_warning", result.getWarnings()));
LogUtils.warn(result.toString());
}
return result.isValid();
}
private String formatErrors(String key, ArrayList<String> errors) {
// TextUtils.format() xml escapes the format arguments - we don't want that
final MessageFormat formatter = new MessageFormat(TextUtils.getText(key));
return formatter.format(new Object[] { StringUtils.join(errors.iterator(), "<br>") });
}
@SuppressWarnings("unchecked")
private void initControls(final DefaultMutableTreeNode controlsTree) {
controls = new Vector<IPropertyControl>();
for (final Enumeration<DefaultMutableTreeNode> i = controlsTree.preorderEnumeration(); i.hasMoreElements();) {
final IPropertyControlCreator creator = (IPropertyControlCreator) i.nextElement().getUserObject();
if (creator == null) {
continue;
}
final IPropertyControl control = creator.createControl();
controls.add(control);
}
}
public void closeWindow() {
final OptionPanelWindowConfigurationStorage storage = new OptionPanelWindowConfigurationStorage();
storage.setPanel(selectedPanel);
storage.storeDialogPositions(topDialog, OptionPanel.PREFERENCE_STORAGE_PROPERTY);
topDialog.setVisible(false);
topDialog.dispose();
}
private Properties getOptionProperties() {
final Properties p = new Properties();
for (final IPropertyControl control : controls) {
if (control instanceof PropertyBean) {
final PropertyBean bean = (PropertyBean) control;
final String value = bean.getValue();
if (value != null) {
p.setProperty(bean.getName(), value);
}
}
}
return p;
}
private JButton getTabButton(final String name) {
return tabButtonMap.get(name);
}
private void registerTabButton(final JButton tabButton, final String name, final ChangeTabAction changeTabAction) {
tabButtonMap.put(name, tabButton);
tabActionMap.put(name, changeTabAction);
if (selectedPanel == null) {
selectedPanel = name;
}
}
public void setProperties() {
for (final IPropertyControl control : controls) {
if (control instanceof PropertyBean) {
final PropertyBean bean = (PropertyBean) control;
final String name = bean.getName();
final String value = ResourceController.getResourceController().getProperty(name);
bean.setValue(value);
}
}
}
void setSelectedPanel(final String panel) {
selectedPanel = panel;
}
}