/*FreeMind - A Program for creating and viewing Mindmaps
*Copyright (C) 2000-2001 Joerg Mueller <joergmueller@bigfoot.com>
*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.
*/
/*$Id: Controller.java,v 1.40.14.21.2.64 2010/02/22 21:18:53 christianfoltin Exp $*/
package freemind.controller;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.HeadlessException;
import java.awt.Insets;
import java.awt.KeyboardFocusManager;
import java.awt.RenderingHints;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.PrinterJob;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Vector;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import freemind.common.BooleanProperty;
import freemind.controller.MapModuleManager.MapModuleChangeObserver;
import freemind.controller.actions.generated.instance.MindmapLastStateStorage;
import freemind.controller.filter.FilterController;
import freemind.controller.printpreview.PreviewDialog;
import freemind.main.FreeMind;
import freemind.main.FreeMindCommon;
import freemind.main.FreeMindMain;
import freemind.main.Resources;
import freemind.main.Tools;
import freemind.modes.MindMap;
import freemind.modes.Mode;
import freemind.modes.ModeController;
import freemind.modes.ModesCreator;
import freemind.modes.attributes.AttributeRegistry;
import freemind.modes.attributes.AttributeTableLayoutModel;
import freemind.modes.browsemode.BrowseMode;
import freemind.modes.mindmapmode.attributeactors.AttributeManagerDialog;
import freemind.preferences.FreemindPropertyListener;
import freemind.preferences.layout.OptionPanel;
import freemind.preferences.layout.OptionPanel.OptionPanelFeedback;
import freemind.view.MapModule;
import freemind.view.mindmapview.MapView;
/**
* Provides the methods to edit/change a Node. Forwards all messages to
* MapModel(editing) or MapView(navigation).
*/
public class Controller implements MapModuleChangeObserver {
/**
*
*/
private static final String PAGE_FORMAT_PROPERTY = "page_format";
private HashSet mMapTitleChangeListenerSet = new HashSet();
private HashSet mZoomListenerSet = new HashSet();
private HashSet mMapTitleContributorSet = new HashSet();
/**
* Converts from a local link to the real file URL of the documentation map.
* (Used to change this behaviour under MacOSX).
*/
private static Logger logger;
/** Used for MAC!!! */
public static LocalLinkConverter localDocumentationLinkConverter;
private static JColorChooser colorChooser = new JColorChooser();
private LastOpenedList lastOpened;// A list of the pathnames of all the maps
// that were opened in the last time
private MapModuleManager mapModuleManager;// new MapModuleManager();
/** The current mode */
private Mode mMode;
private FreeMindMain frame;
private MainToolBar toolbar;
private JToolBar filterToolbar;
private JPanel northToolbarPanel;
private NodeMouseMotionListener nodeMouseMotionListener;
private NodeMotionListener nodeMotionListener;
private NodeKeyListener nodeKeyListener;
private NodeDragListener nodeDragListener;
private NodeDropListener nodeDropListener;
private MapMouseMotionListener mapMouseMotionListener;
private MapMouseWheelListener mapMouseWheelListener;
private ModesCreator mModescreator = new ModesCreator(this);
private PageFormat pageFormat = null;
private PrinterJob printerJob = null;
private Icon bswatch = new BackgroundSwatch();// needed for BackgroundAction
private boolean antialiasEdges = false;
private boolean antialiasAll = false;
private Map fontMap = new HashMap();
private FilterController mFilterController;
boolean isPrintingAllowed = true;
boolean menubarVisible = true;
boolean toolbarVisible = true;
boolean leftToolbarVisible = true;
public CloseAction close;
public Action print;
public Action printDirect;
public Action printPreview;
public Action page;
public Action quit;
public Action showAllAttributes = new ShowAllAttributesAction();
public Action showSelectedAttributes = new ShowSelectedAttributesAction();
public Action hideAllAttributes = new HideAllAttributesAction();
public OptionAntialiasAction optionAntialiasAction;
public Action optionHTMLExportFoldingAction;
public Action optionSelectionMechanismAction;
public Action about;
public Action faq;
public Action keyDocumentation;
public Action webDocu;
public Action documentation;
public Action license;
public Action showFilterToolbarAction;
public Action showAttributeManagerAction;
public Action navigationPreviousMap;
public Action navigationNextMap;
public Action navigationMoveMapLeftAction;
public Action navigationMoveMapRightAction;
public Action moveToRoot;
public Action toggleMenubar;
public Action toggleToolbar;
public Action toggleLeftToolbar;
public Action zoomIn;
public Action zoomOut;
public Action showSelectionAsRectangle;
public PropertyAction propertyAction;
public OpenURLAction freemindUrl;
private static final float[] zoomValues = { 25 / 100f, 50 / 100f,
75 / 100f, 100 / 100f, 150 / 100f, 200 / 100f, 300 / 100f,
400 / 100f };
private static Vector propertyChangeListeners = new Vector();
private AttributeManagerDialog attributeDialog = null;
private Vector mTabbedPaneMapModules;
private JTabbedPane mTabbedPane;
private boolean mTabbedPaneSelectionUpdate = true;
//
// Constructors
//
public Controller(FreeMindMain frame) {
this.frame = frame;
if (logger == null) {
logger = frame.getLogger(this.getClass().getName());
}
}
public void init() {
initialization();
nodeMouseMotionListener = new NodeMouseMotionListener(this);
nodeMotionListener = new NodeMotionListener(this);
nodeKeyListener = new NodeKeyListener(this);
nodeDragListener = new NodeDragListener(this);
nodeDropListener = new NodeDropListener(this);
mapMouseMotionListener = new MapMouseMotionListener(this);
mapMouseWheelListener = new MapMouseWheelListener(this);
close = new CloseAction(this);
print = new PrintAction(this, true);
printDirect = new PrintAction(this, false);
printPreview = new PrintPreviewAction(this);
page = new PageAction(this);
quit = new QuitAction(this);
about = new AboutAction(this);
freemindUrl = new OpenURLAction(this, getResourceString("FreeMind"),
getProperty("webFreeMindLocation"));
faq = new OpenURLAction(this, getResourceString("FAQ"),
getProperty("webFAQLocation"));
keyDocumentation = new KeyDocumentationAction(this);
webDocu = new OpenURLAction(this, getResourceString("webDocu"),
getProperty("webDocuLocation"));
documentation = new DocumentationAction(this);
license = new LicenseAction(this);
navigationPreviousMap = new NavigationPreviousMapAction(this);
navigationNextMap = new NavigationNextMapAction(this);
navigationMoveMapLeftAction = new NavigationMoveMapLeftAction(this);
navigationMoveMapRightAction = new NavigationMoveMapRightAction(this);
showFilterToolbarAction = new ShowFilterToolbarAction(this);
showAttributeManagerAction = new ShowAttributeDialogAction(this);
toggleMenubar = new ToggleMenubarAction(this);
toggleToolbar = new ToggleToolbarAction(this);
toggleLeftToolbar = new ToggleLeftToolbarAction(this);
optionAntialiasAction = new OptionAntialiasAction(this);
optionHTMLExportFoldingAction = new OptionHTMLExportFoldingAction(this);
optionSelectionMechanismAction = new OptionSelectionMechanismAction(
this);
zoomIn = new ZoomInAction(this);
zoomOut = new ZoomOutAction(this);
propertyAction = new PropertyAction(this);
showSelectionAsRectangle = new ShowSelectionAsRectangleAction(this);
moveToRoot = new MoveToRootAction(this);
// Create the ToolBar
northToolbarPanel = new JPanel(new BorderLayout());
toolbar = new MainToolBar(this);
mFilterController = new FilterController(this);
filterToolbar = mFilterController.getFilterToolbar();
getFrame().getContentPane().add(northToolbarPanel, BorderLayout.NORTH);
northToolbarPanel.add(toolbar, BorderLayout.NORTH);
northToolbarPanel.add(filterToolbar, BorderLayout.SOUTH);
setAllActions(false);
}
/**
* Does basic initializations of this class. Normally, init is called, but
* if you don't need the actions, call this method instead.
*/
public void initialization() {
/**
* Arranges the keyboard focus especially after opening FreeMind.
* */
KeyboardFocusManager focusManager = KeyboardFocusManager
.getCurrentKeyboardFocusManager();
focusManager.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent e) {
String prop = e.getPropertyName();
if ("focusOwner".equals(prop)) {
Component comp = (Component) e.getNewValue();
logger.fine("Focus change for " + comp);
if (comp instanceof FreeMindMain) {
obtainFocusForSelected();
}
}
}
});
localDocumentationLinkConverter = new DefaultLocalLinkConverter();
lastOpened = new LastOpenedList(this, getProperty("lastOpened"));
mapModuleManager = new MapModuleManager(this);
mapModuleManager.addListener(this);
if (!Tools.isAvailableFontFamily(getProperty("defaultfont"))) {
logger.warning("Warning: the font you have set as standard - "
+ getProperty("defaultfont") + " - is not available.");
frame.setProperty("defaultfont", "SansSerif");
}
}
//
// get/set methods
//
public static final String JAVA_VERSION = System
.getProperty("java.version");
public String getProperty(String property) {
return frame.getProperty(property);
}
public int getIntProperty(String property, int defaultValue) {
return frame.getIntProperty(property, defaultValue);
}
public void setProperty(String property, String value) {
String oldValue = getProperty(property);
getFrame().setProperty(property, value);
firePropertyChanged(property, value, oldValue);
}
private void firePropertyChanged(String property, String value,
String oldValue) {
if (oldValue == null || !oldValue.equals(value)) {
for (Iterator i = Controller.getPropertyChangeListeners()
.iterator(); i.hasNext();) {
FreemindPropertyListener listener = (FreemindPropertyListener) i
.next();
listener.propertyChanged(property, value, oldValue);
}
}
}
public FreeMindMain getFrame() {
return frame;
}
public JFrame getJFrame() {
FreeMindMain f = getFrame();
if (f instanceof JFrame)
return (JFrame) f;
return null;
}
public URL getResource(String resource) {
return getFrame().getResource(resource);
}
public String getResourceString(String resource) {
return frame.getResourceString(resource);
}
/**
* @return the current modeController, or null, if FreeMind is just starting
* and there is no modeController present.
*/
public ModeController getModeController() {
if (getMapModule() != null) {
return getMapModule().getModeController();
}
if (getMode() != null) {
// no map present: we take the default:
return getMode().getDefaultModeController();
}
return null;
}
/** Returns the current model */
public MindMap getModel() {
if (getMapModule() != null) {
return getMapModule().getModel();
}
return null;
}
public MapView getView() {
if (getMapModule() != null) {
return getMapModule().getView();
} else {
// System.err.println("[Freemind-Developer-Internal-Warning (do not write a bug report, please)]: Tried to get view without being able to get map module.");
return null;
}
}
Set getModes() {
return mModescreator.getAllModes();
}
public Mode getMode() {
return mMode;
}
public String[] getZooms() {
String[] zooms = new String[zoomValues.length];
for (int i = 0; i < zoomValues.length; i++) {
float val = zoomValues[i];
zooms[i] = (int) (val * 100f) + "%";
}
return zooms;
}
public MapModuleManager getMapModuleManager() {
return mapModuleManager;
}
public LastOpenedList getLastOpenedList() {
return lastOpened;
}
//
public MapModule getMapModule() {
return getMapModuleManager().getMapModule();
}
private JToolBar getToolBar() {
return toolbar;
}
//
public Font getFontThroughMap(Font font) {
if (!fontMap.containsKey(font.toString())) {
fontMap.put(font.toString(), font);
}
return (Font) fontMap.get(font.toString());
}
//
public void setAntialiasEdges(boolean antialiasEdges) {
this.antialiasEdges = antialiasEdges;
}
public void setAntialiasAll(boolean antialiasAll) {
this.antialiasAll = antialiasAll;
}
private boolean getAntialiasEdges() {
return antialiasEdges;
}
private boolean getAntialiasAll() {
return antialiasAll;
}
public Font getDefaultFont() {
// Maybe implement handling for cases when the font is not
// available on this system.
int fontSize = getDefaultFontSize();
int fontStyle = getDefaultFontStyle();
String fontFamily = getDefaultFontFamilyName();
return getFontThroughMap(new Font(fontFamily, fontStyle, fontSize));
}
/**
*/
public String getDefaultFontFamilyName() {
String fontFamily = getProperty("defaultfont");
return fontFamily;
}
/**
*/
public int getDefaultFontStyle() {
int fontStyle = frame.getIntProperty("defaultfontstyle", 0);
return fontStyle;
}
/**
*/
public int getDefaultFontSize() {
int fontSize = frame.getIntProperty("defaultfontsize", 12);
return fontSize;
}
/** Static JColorChooser to have the recent colors feature. */
static public JColorChooser getCommonJColorChooser() {
return colorChooser;
}
public static Color showCommonJColorChooserDialog(Component component,
String title, Color initialColor) throws HeadlessException {
final JColorChooser pane = getCommonJColorChooser();
pane.setColor(initialColor);
ColorTracker ok = new ColorTracker(pane);
JDialog dialog = JColorChooser.createDialog(component, title, true,
pane, ok, null);
dialog.addWindowListener(new Closer());
dialog.addComponentListener(new DisposeOnClose());
dialog.show(); // blocks until user brings dialog down...
return ok.getColor();
}
private static class ColorTracker implements ActionListener, Serializable {
JColorChooser chooser;
Color color;
public ColorTracker(JColorChooser c) {
chooser = c;
}
public void actionPerformed(ActionEvent e) {
color = chooser.getColor();
}
public Color getColor() {
return color;
}
}
static class Closer extends WindowAdapter implements Serializable {
public void windowClosing(WindowEvent e) {
Window w = e.getWindow();
w.hide();
}
}
static class DisposeOnClose extends ComponentAdapter implements
Serializable {
public void componentHidden(ComponentEvent e) {
Window w = (Window) e.getComponent();
w.dispose();
}
}
public boolean isMapModuleChangeAllowed(MapModule oldMapModule,
Mode oldMode, MapModule newMapModule, Mode newMode) {
return true;
}
public void afterMapClose(MapModule pOldMapModule, Mode pOldMode) {
}
public void beforeMapModuleChange(MapModule oldMapModule, Mode oldMode,
MapModule newMapModule, Mode newMode) {
ModeController oldModeController;
this.mMode = newMode;
if (oldMapModule != null) {
// shut down screens of old view + frame
oldModeController = oldMapModule.getModeController();
oldModeController.setVisible(false);
oldModeController.shutdownController();
} else {
if (oldMode != null) {
oldModeController = oldMode.getDefaultModeController();
} else {
return;
}
}
if (oldModeController.getModeToolBar() != null) {
toolbar.remove(oldModeController.getModeToolBar());
toolbar.activate(true);
// northToolbarPanel.remove(oldModeController.getModeToolBar());
// northToolbarPanel.add(toolbar, BorderLayout.NORTH);
}
/* other toolbars are to be removed too. */
if (oldModeController.getLeftToolBar() != null) {
getFrame().getContentPane().remove(
oldModeController.getLeftToolBar());
}
}
public void afterMapModuleChange(MapModule oldMapModule, Mode oldMode,
MapModule newMapModule, Mode newMode) {
ModeController newModeController;
if (newMapModule != null) {
getFrame().setView(newMapModule.getView());
setAllActions(true);
if ((getView().getSelected() == null)) {
// moveToRoot();
getView().selectAsTheOnlyOneSelected(getView().getRoot());
}
lastOpened.mapOpened(newMapModule);
changeZoomValueProperty(newMapModule.getView().getZoom());
// ((MainToolBar) getToolbar()).setZoomComboBox(zoomValue);
// old
// obtainFocusForSelected();
newModeController = newMapModule.getModeController();
newModeController.startupController();
newModeController.setVisible(true);
// old
// obtainFocusForSelected();
} else {
newModeController = newMode.getDefaultModeController();
getFrame().setView(null);
setAllActions(false);
}
setTitle();
JToolBar newToolBar = newModeController.getModeToolBar();
if (newToolBar != null) {
toolbar.activate(false);
toolbar.add(newToolBar, 0);
// northToolbarPanel.remove(toolbar);
// northToolbarPanel.add(newToolBar, BorderLayout.NORTH);
newToolBar.repaint();
}
/* new left toolbar. */
Component newLeftToolBar = newModeController.getLeftToolBar();
if (newLeftToolBar != null) {
getFrame().getContentPane().add(newLeftToolBar, BorderLayout.WEST);
if (leftToolbarVisible) {
newLeftToolBar.setVisible(true);
newLeftToolBar.repaint();
} else {
newLeftToolBar.setVisible(false);
}
}
toolbar.validate();
toolbar.repaint();
MenuBar menuBar = getFrame().getFreeMindMenuBar();
menuBar.updateMenus(newModeController);
menuBar.revalidate();
menuBar.repaint();
// new
obtainFocusForSelected();
}
protected void changeZoomValueProperty(final float zoomValue) {
for (Iterator it = mZoomListenerSet.iterator(); it.hasNext();) {
ZoomListener listener = (ZoomListener) it.next();
listener.setZoom(zoomValue);
}
}
public void numberOfOpenMapInformation(int number, int pIndex) {
navigationPreviousMap.setEnabled(number > 0);
navigationNextMap.setEnabled(number > 0);
logger.info("number " + number + ", pIndex " + pIndex);
navigationMoveMapLeftAction.setEnabled(number > 1 && pIndex > 0);
navigationMoveMapRightAction.setEnabled(number > 1
&& pIndex < number - 1);
}
/**
* Creates a new mode (controller), activates the toolbars, title and
* deactivates all actions. Does nothing, if the mode is identical to the
* current mode.
*
* @return false if the change was not successful.
*/
public boolean createNewMode(String mode) {
if (getMode() != null && mode.equals(getMode().toString())) {
return true;
}
// Check if the mode is available and create ModeController.
Mode newMode = mModescreator.getMode(mode);
if (newMode == null) {
errorMessage(getResourceString("mode_na") + ": " + mode);
return false;
}
// change the map module to get changed toolbars etc.:
getMapModuleManager().setMapModule(null, newMode);
setTitle();
getMode().activate();
Object[] messageArguments = { getMode().toLocalizedString() };
MessageFormat formatter = new MessageFormat(
getResourceString("mode_status"));
getFrame().out(formatter.format(messageArguments));
return true;
}
public void setMenubarVisible(boolean visible) {
menubarVisible = visible;
getFrame().getFreeMindMenuBar().setVisible(menubarVisible);
}
public void setToolbarVisible(boolean visible) {
toolbarVisible = visible;
toolbar.setVisible(toolbarVisible);
}
/**
* @return Returns the main toolbar.
*/
public JToolBar getToolbar() {
return toolbar;
}
public void setLeftToolbarVisible(boolean visible) {
leftToolbarVisible = visible;
if (getMode() == null) {
return;
}
final Component leftToolBar = getModeController().getLeftToolBar();
if (leftToolBar != null) {
leftToolBar.setVisible(leftToolbarVisible);
((JComponent) leftToolBar.getParent()).revalidate();
}
}
public NodeKeyListener getNodeKeyListener() {
return nodeKeyListener;
}
public NodeMouseMotionListener getNodeMouseMotionListener() {
return nodeMouseMotionListener;
}
public NodeMotionListener getNodeMotionListener() {
return nodeMotionListener;
}
public MapMouseMotionListener getMapMouseMotionListener() {
return mapMouseMotionListener;
}
public MapMouseWheelListener getMapMouseWheelListener() {
return mapMouseWheelListener;
}
public NodeDragListener getNodeDragListener() {
return nodeDragListener;
}
public NodeDropListener getNodeDropListener() {
return nodeDropListener;
}
public void setFrame(FreeMindMain frame) {
this.frame = frame;
}
/**
* I don't understand how this works now (it's called twice etc.) but it
* _works_ now. So let it alone or fix it to be understandable, if you have
* the time ;-)
*/
void moveToRoot() {
if (getMapModule() != null) {
getView().moveToRoot();
}
}
/**
* Closes the actual map.
*
* @param force
* true= without save.
*/
public void close(boolean force) {
getMapModuleManager().close(force, null);
}
// (PN) %%%
// public void select( NodeView node) {
// getView().select(node,false);
// getView().setSiblingMaxLevel(node.getModel().getNodeLevel()); // this
// level is default
// }
//
// void selectBranch( NodeView node, boolean extend ) {
// getView().selectBranch(node,extend);
// }
//
// boolean isSelected( NodeView node ) {
// return getView().isSelected(node);
// }
//
// void centerNode() {
// getView().centerNode(getView().getSelected());
// }
//
// private MindMapNode getSelected() {
// return getView().getSelected().getModel();
// }
public void informationMessage(Object message) {
JOptionPane
.showMessageDialog(getFrame().getContentPane(),
message.toString(), "FreeMind",
JOptionPane.INFORMATION_MESSAGE);
}
public void informationMessage(Object message, JComponent component) {
JOptionPane.showMessageDialog(component, message.toString(),
"FreeMind", JOptionPane.INFORMATION_MESSAGE);
}
public void errorMessage(Object message) {
String myMessage = "";
if (message != null) {
myMessage = message.toString();
} else {
myMessage = getResourceString("undefined_error");
if (myMessage == null) {
myMessage = "Undefined error";
}
}
JOptionPane.showMessageDialog(getFrame().getContentPane(), myMessage,
"FreeMind", JOptionPane.ERROR_MESSAGE);
}
public void errorMessage(Object message, JComponent component) {
JOptionPane.showMessageDialog(component, message.toString(),
"FreeMind", JOptionPane.ERROR_MESSAGE);
}
public void obtainFocusForSelected() {
// logger.finest("obtainFocusForSelected");
if (getView() != null) { // is null if the last map was closed.
logger.fine("Requesting Focus for " + getView() + " in model "
+ getView().getModel());
getView().requestFocusInWindow();
} else {
// fc, 6.1.2004: bug fix, that open and quit are not working if no
// map is present.
// to avoid this, the menu bar gets the focus, and everything seems
// to be all right!!
// but I cannot avoid thinking of this change to be a bad hack ....
logger.info("No view present. No focus!");
getFrame().getFreeMindMenuBar().requestFocus();
}
}
//
// Map Navigation
//
//
// other
//
public void setZoom(float zoom) {
getView().setZoom(zoom);
changeZoomValueProperty(zoom);
// ((MainToolBar) toolbar).setZoomComboBox(zoom);
// show text in status bar:
Object[] messageArguments = { String.valueOf(zoom * 100f) };
String stringResult = Resources.getInstance().format(
"user_defined_zoom_status_bar", messageArguments);
getFrame().out(stringResult);
}
// ////////////
// Private methods. Internal implementation
// //////////
//
// Node editing
//
// (PN)
// private void getFocus() {
// getView().getSelected().requestFocus();
// }
//
// Multiple Views management
//
/**
* Set the Frame title with mode and file if exist
*/
public void setTitle() {
Object[] messageArguments = { getMode().toLocalizedString() };
MessageFormat formatter = new MessageFormat(
getResourceString("mode_title"));
String title = formatter.format(messageArguments);
String rawTitle = "";
MindMap model = null;
MapModule mapModule = getMapModule();
if (mapModule != null) {
model = mapModule.getModel();
rawTitle = mapModule.toString();
title = rawTitle
+ (model.isSaved() ? "" : "*")
+ " - "
+ title
+ (model.isReadOnly() ? " ("
+ getResourceString("read_only") + ")" : "");
File file = model.getFile();
if (file != null) {
title += " " + file.getAbsolutePath();
}
for (Iterator iterator = mMapTitleContributorSet.iterator(); iterator
.hasNext();) {
MapModuleManager.MapTitleContributor contributor = (MapModuleManager.MapTitleContributor) iterator
.next();
title = contributor.getMapTitle(title, mapModule, model);
}
}
getFrame().setTitle(title);
for (Iterator iterator = mMapTitleChangeListenerSet.iterator(); iterator
.hasNext();) {
MapModuleManager.MapTitleChangeListener listener = (MapModuleManager.MapTitleChangeListener) iterator
.next();
listener.setMapTitle(rawTitle, mapModule, model);
}
}
public void registerMapTitleChangeListener(
MapModuleManager.MapTitleChangeListener pMapTitleChangeListener) {
mMapTitleChangeListenerSet.add(pMapTitleChangeListener);
}
public void deregisterMapTitleChangeListener(
MapModuleManager.MapTitleChangeListener pMapTitleChangeListener) {
mMapTitleChangeListenerSet.remove(pMapTitleChangeListener);
}
public void registerZoomListener(ZoomListener pZoomListener) {
mZoomListenerSet.add(pZoomListener);
}
public void deregisterZoomListener(ZoomListener pZoomListener) {
mZoomListenerSet.remove(pZoomListener);
}
public void registerMapTitleContributor(
MapModuleManager.MapTitleContributor pMapTitleContributor) {
mMapTitleContributorSet.add(pMapTitleContributor);
}
public void deregisterMapTitleContributor(
MapModuleManager.MapTitleContributor pMapTitleContributor) {
mMapTitleContributorSet.remove(pMapTitleContributor);
}
//
// Actions management
//
/**
* Manage the availabilty of all Actions dependend of whether there is a map
* or not
*/
public void setAllActions(boolean enabled) {
print.setEnabled(enabled && isPrintingAllowed);
printDirect.setEnabled(enabled && isPrintingAllowed);
printPreview.setEnabled(enabled && isPrintingAllowed);
page.setEnabled(enabled && isPrintingAllowed);
close.setEnabled(enabled);
moveToRoot.setEnabled(enabled);
showAllAttributes.setEnabled(enabled);
showSelectedAttributes.setEnabled(enabled);
hideAllAttributes.setEnabled(enabled);
showAttributeManagerAction.setEnabled(enabled);
((MainToolBar) getToolBar()).setAllActions(enabled);
showSelectionAsRectangle.setEnabled(enabled);
}
//
// program/map control
//
private void quit() {
String currentMapRestorable = (getModel() != null) ? getModel()
.getRestorable() : null;
// collect all maps:
Vector restorables = new Vector();
// move to first map in the window.
List mapModuleVector = getMapModuleManager().getMapModuleVector();
if (mapModuleVector.size() > 0) {
String displayName = ((MapModule) mapModuleVector.get(0))
.getDisplayName();
getMapModuleManager().changeToMapModule(displayName);
}
while (mapModuleVector.size() > 0) {
if (getMapModule() != null) {
StringBuffer restorableBuffer = new StringBuffer();
boolean closingNotCancelled = getMapModuleManager().close(
false, restorableBuffer);
if (!closingNotCancelled) {
return;
}
if (restorableBuffer.length() != 0) {
String restorableString = restorableBuffer.toString();
logger.info("Closed the map " + restorableString);
restorables.add(restorableString);
}
} else {
// map module without view open.
// FIXME: This seems to be a bad hack. correct me!
getMapModuleManager().nextMapModule();
}
}
// store last tab session:
int index = 0;
String lastStateMapXml = getProperty(FreeMindCommon.MINDMAP_LAST_STATE_MAP_STORAGE);
LastStateStorageManagement management = new LastStateStorageManagement(
lastStateMapXml);
management.setLastFocussedTab(-1);
management.clearTabIndices();
for (Iterator it = restorables.iterator(); it.hasNext();) {
String restorable = (String) it.next();
MindmapLastStateStorage storage = management.getStorage(restorable);
if (storage != null) {
storage.setTabIndex(index);
}
if (Tools.safeEquals(restorable, currentMapRestorable)) {
management.setLastFocussedTab(index);
}
index++;
}
setProperty(FreeMindCommon.MINDMAP_LAST_STATE_MAP_STORAGE,
management.getXml());
String lastOpenedString = lastOpened.save();
setProperty("lastOpened", lastOpenedString);
getFrame().setProperty(FreeMindCommon.ON_START_IF_NOT_SPECIFIED,
currentMapRestorable != null ? currentMapRestorable : "");
// getFrame().setProperty("menubarVisible",menubarVisible ? "true" :
// "false");
// ^ Not allowed in application because of problems with not working key
// shortcuts
setProperty("toolbarVisible", toolbarVisible ? "true" : "false");
setProperty("leftToolbarVisible", leftToolbarVisible ? "true" : "false");
setProperty("antialiasEdges", antialiasEdges ? "true" : "false");
setProperty("antialiasAll", antialiasAll ? "true" : "false");
if (!getFrame().isApplet()) {
final int winState = getFrame().getWinState();
if (JFrame.MAXIMIZED_BOTH != (winState & JFrame.MAXIMIZED_BOTH)) {
setProperty("appwindow_x", String.valueOf(getFrame().getWinX()));
setProperty("appwindow_y", String.valueOf(getFrame().getWinY()));
setProperty("appwindow_width",
String.valueOf(getFrame().getWinWidth()));
setProperty("appwindow_height",
String.valueOf(getFrame().getWinHeight()));
}
setProperty("appwindow_state", String.valueOf(winState));
}
// Stop edit server!
getFrame().saveProperties(true);
// save to properties
System.exit(0);
}
private boolean acquirePrinterJobAndPageFormat() {
if (printerJob == null) {
try {
printerJob = PrinterJob.getPrinterJob();
} catch (SecurityException ex) {
isPrintingAllowed = false;
return false;
}
}
if (pageFormat == null) {
pageFormat = printerJob.defaultPage();
}
if (Tools.safeEquals(getProperty("page_orientation"), "landscape")) {
pageFormat.setOrientation(PageFormat.LANDSCAPE);
} else if (Tools
.safeEquals(getProperty("page_orientation"), "portrait")) {
pageFormat.setOrientation(PageFormat.PORTRAIT);
} else if (Tools.safeEquals(getProperty("page_orientation"),
"reverse_landscape")) {
pageFormat.setOrientation(PageFormat.REVERSE_LANDSCAPE);
}
String pageFormatProperty = getProperty(PAGE_FORMAT_PROPERTY);
if (!pageFormatProperty.isEmpty()) {
logger.info("Page format (stored): " + pageFormatProperty);
final Paper storedPaper = new Paper();
Tools.setPageFormatFromString(storedPaper, pageFormatProperty);
pageFormat.setPaper(storedPaper);
}
return true;
}
// ////////////
// Inner Classes
// //////////
/**
* Manages the history of visited maps. Maybe explicitly closed maps should
* be removed from History too?
*/
//
// program/map control
//
private class QuitAction extends AbstractAction {
QuitAction(Controller controller) {
super(controller.getResourceString("quit"));
}
public void actionPerformed(ActionEvent e) {
quit();
}
}
/** This closes only the current map */
public static class CloseAction extends AbstractAction {
private final Controller controller;
CloseAction(Controller controller) {
Tools.setLabelAndMnemonic(this,
controller.getResourceString("close"));
this.controller = controller;
}
public void actionPerformed(ActionEvent e) {
controller.close(false);
}
}
private class PrintAction extends AbstractAction {
Controller controller;
boolean isDlg;
PrintAction(Controller controller, boolean isDlg) {
super(isDlg ? controller.getResourceString("print_dialog")
: controller.getResourceString("print"), new ImageIcon(
getResource("images/fileprint.png")));
this.controller = controller;
setEnabled(false);
this.isDlg = isDlg;
}
public void actionPerformed(ActionEvent e) {
if (!acquirePrinterJobAndPageFormat()) {
return;
}
printerJob.setPrintable(getView(), pageFormat);
if (!isDlg || printerJob.printDialog()) {
try {
frame.setWaitingCursor(true);
printerJob.print();
storePageFormat();
} catch (Exception ex) {
freemind.main.Resources.getInstance().logException(ex);
} finally {
frame.setWaitingCursor(false);
}
}
}
}
private class PrintPreviewAction extends AbstractAction {
Controller controller;
PrintPreviewAction(Controller controller) {
super(controller.getResourceString("print_preview"));
this.controller = controller;
}
public void actionPerformed(ActionEvent e) {
if (!acquirePrinterJobAndPageFormat()) {
return;
}
PreviewDialog previewDialog = new PreviewDialog(
controller.getResourceString("print_preview_title"),
getView());
previewDialog.pack();
previewDialog.setLocationRelativeTo(JOptionPane
.getFrameForComponent(getView()));
previewDialog.setVisible(true);
}
}
private class PageAction extends AbstractAction {
Controller controller;
PageAction(Controller controller) {
super(controller.getResourceString("page"));
this.controller = controller;
setEnabled(false);
}
public void actionPerformed(ActionEvent e) {
if (!acquirePrinterJobAndPageFormat()) {
return;
}
// Ask about custom printing settings
final JDialog dialog = new JDialog((JFrame) getFrame(),
getResourceString("printing_settings"), /* modal= */true);
final JCheckBox fitToPage = new JCheckBox(
getResourceString("fit_to_page"), Resources.getInstance()
.getBoolProperty("fit_to_page"));
final JLabel userZoomL = new JLabel(getResourceString("user_zoom"));
final JTextField userZoom = new JTextField(
getProperty("user_zoom"), 3);
userZoom.setEditable(!fitToPage.isSelected());
final JButton okButton = new JButton();
Tools.setLabelAndMnemonic(okButton, getResourceString("ok"));
final Tools.IntHolder eventSource = new Tools.IntHolder();
JPanel panel = new JPanel();
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
eventSource.setValue(0);
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
eventSource.setValue(1);
dialog.dispose();
}
});
fitToPage.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
userZoom.setEditable(e.getStateChange() == ItemEvent.DESELECTED);
}
});
// c.weightx = 0.5;
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 2;
gridbag.setConstraints(fitToPage, c);
panel.add(fitToPage);
c.gridy = 1;
c.gridwidth = 1;
gridbag.setConstraints(userZoomL, c);
panel.add(userZoomL);
c.gridx = 1;
c.gridwidth = 1;
gridbag.setConstraints(userZoom, c);
panel.add(userZoom);
c.gridy = 2;
c.gridx = 0;
c.gridwidth = 3;
c.insets = new Insets(10, 0, 0, 0);
gridbag.setConstraints(okButton, c);
panel.add(okButton);
panel.setLayout(gridbag);
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setContentPane(panel);
dialog.setLocationRelativeTo((JFrame) getFrame());
dialog.getRootPane().setDefaultButton(okButton);
dialog.pack(); // calculate the size
dialog.setVisible(true);
if (eventSource.getValue() == 1) {
setProperty("user_zoom", userZoom.getText());
setProperty("fit_to_page", fitToPage.isSelected() ? "true"
: "false");
} else
return;
// Ask user for page format (e.g., portrait/landscape)
pageFormat = printerJob.pageDialog(pageFormat);
storePageFormat();
}
}
public interface LocalLinkConverter {
/**
* @throws MalformedURLException
* if the conversion didn't work
*/
URL convertLocalLink(String link) throws MalformedURLException;
}
private class DefaultLocalLinkConverter implements LocalLinkConverter {
public URL convertLocalLink(String map) throws MalformedURLException {
/* new handling for relative urls. fc, 29.10.2003. */
String applicationPath = frame.getFreemindBaseDir();
// remove "." and make url
return Tools
.fileToUrl(new File(applicationPath + map.substring(1)));
/* end: new handling for relative urls. fc, 29.10.2003. */
}
}
//
// Help
//
private class DocumentationAction extends AbstractAction {
Controller controller;
DocumentationAction(Controller controller) {
super(controller.getResourceString("documentation"));
this.controller = controller;
}
public void actionPerformed(ActionEvent e) {
try {
String map = controller.getFrame().getResourceString(
"browsemode_initial_map");
// if the current language does not provide its own translation,
// POSTFIX_TRANSLATE_ME is appended:
map = Tools.removeTranslateComment(map);
URL url = null;
if (map != null && map.startsWith(".")) {
url = localDocumentationLinkConverter.convertLocalLink(map);
} else {
url = Tools.fileToUrl(new File(map));
}
final URL endUrl = url;
// invokeLater is necessary, as the mode changing removes
// all
// menus (inclusive this action!).
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
createNewMode(BrowseMode.MODENAME);
controller.getModeController().load(endUrl);
} catch (Exception e1) {
freemind.main.Resources.getInstance().logException(
e1);
}
}
});
} catch (MalformedURLException e1) {
// TODO Auto-generated catch block
freemind.main.Resources.getInstance().logException(e1);
}
}
}
private class KeyDocumentationAction extends AbstractAction {
Controller controller;
KeyDocumentationAction(Controller controller) {
super(controller.getResourceString("KeyDoc"));
this.controller = controller;
}
public void actionPerformed(ActionEvent e) {
String urlText = controller.getFrame().getResourceString(
"pdfKeyDocLocation");
// if the current language does not provide its own translation,
// POSTFIX_TRANSLATE_ME is appended:
urlText = Tools.removeTranslateComment(urlText);
try {
URL url = null;
if (urlText != null && urlText.startsWith(".")) {
url = localDocumentationLinkConverter
.convertLocalLink(urlText);
} else {
url = Tools.fileToUrl(new File(urlText));
}
logger.info("Opening key docs under " + url);
controller.getFrame().openDocument(url);
} catch (Exception e2) {
freemind.main.Resources.getInstance().logException(e2);
return;
}
}
}
private class AboutAction extends AbstractAction {
Controller controller;
AboutAction(Controller controller) {
super(controller.getResourceString("about"));
this.controller = controller;
}
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(getView(),
controller.getResourceString("about_text")
+ getFrame().getFreemindVersion()
+ " "
+ FreeMind.HACKEDVERSION,
controller.getResourceString("about"),
JOptionPane.INFORMATION_MESSAGE);
}
}
private class LicenseAction extends AbstractAction {
Controller controller;
LicenseAction(Controller controller) {
super(controller.getResourceString("license"));
this.controller = controller;
}
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(getView(),
controller.getResourceString("license_text"),
controller.getResourceString("license"),
JOptionPane.INFORMATION_MESSAGE);
}
}
//
// Map navigation
//
private class NavigationPreviousMapAction extends AbstractAction {
NavigationPreviousMapAction(Controller controller) {
super(controller.getResourceString("previous_map"), new ImageIcon(
getResource("images/1leftarrow.png")));
setEnabled(false);
}
public void actionPerformed(ActionEvent event) {
mapModuleManager.previousMapModule();
}
}
private class ShowAttributeDialogAction extends AbstractAction {
private Controller c;
ShowAttributeDialogAction(Controller c) {
super(c.getResourceString("attributes_dialog"), new ImageIcon(
getResource("images/showAttributes.gif")));
this.c = c;
}
private AttributeManagerDialog getAttributeDialog() {
if (attributeDialog == null) {
attributeDialog = new AttributeManagerDialog(c);
}
return attributeDialog;
}
public void actionPerformed(ActionEvent e) {
if (getAttributeDialog().isVisible() == false
&& getMapModule() != null) {
getAttributeDialog().pack();
getAttributeDialog().show();
}
}
}
private class ShowFilterToolbarAction extends AbstractAction {
ShowFilterToolbarAction(Controller controller) {
super(getResourceString("filter_toolbar"), new ImageIcon(
getResource("images/filter.gif")));
}
public void actionPerformed(ActionEvent event) {
if (!getFilterController().isVisible()) {
getFilterController().showFilterToolbar(true);
} else {
getFilterController().showFilterToolbar(false);
}
}
}
private class NavigationNextMapAction extends AbstractAction {
NavigationNextMapAction(Controller controller) {
super(controller.getResourceString("next_map"), new ImageIcon(
getResource("images/1rightarrow.png")));
setEnabled(false);
}
public void actionPerformed(ActionEvent event) {
mapModuleManager.nextMapModule();
}
}
private class NavigationMoveMapLeftAction extends AbstractAction {
NavigationMoveMapLeftAction(Controller controller) {
super(controller.getResourceString("move_map_left"), new ImageIcon(
getResource("images/draw-arrow-back.png")));
setEnabled(false);
}
public void actionPerformed(ActionEvent event) {
if (mTabbedPane != null) {
int selectedIndex = mTabbedPane.getSelectedIndex();
int previousIndex = (selectedIndex > 0) ? (selectedIndex - 1)
: (mTabbedPane.getTabCount() - 1);
moveTab(selectedIndex, previousIndex);
}
}
}
private class NavigationMoveMapRightAction extends AbstractAction {
NavigationMoveMapRightAction(Controller controller) {
super(controller.getResourceString("move_map_right"),
new ImageIcon(getResource("images/draw-arrow-forward.png")));
setEnabled(false);
}
public void actionPerformed(ActionEvent event) {
if (mTabbedPane != null) {
int selectedIndex = mTabbedPane.getSelectedIndex();
int previousIndex = (selectedIndex >= mTabbedPane.getTabCount() - 1) ? 0
: (selectedIndex + 1);
moveTab(selectedIndex, previousIndex);
}
}
}
public void moveTab(int src, int dst) {
// snippet taken from
// http://www.exampledepot.com/egs/javax.swing/tabbed_TpMove.html
// Get all the properties
Component comp = mTabbedPane.getComponentAt(src);
String label = mTabbedPane.getTitleAt(src);
Icon icon = mTabbedPane.getIconAt(src);
Icon iconDis = mTabbedPane.getDisabledIconAt(src);
String tooltip = mTabbedPane.getToolTipTextAt(src);
boolean enabled = mTabbedPane.isEnabledAt(src);
int keycode = mTabbedPane.getMnemonicAt(src);
int mnemonicLoc = mTabbedPane.getDisplayedMnemonicIndexAt(src);
Color fg = mTabbedPane.getForegroundAt(src);
Color bg = mTabbedPane.getBackgroundAt(src);
mTabbedPaneSelectionUpdate = false;
// Remove the tab
mTabbedPane.remove(src);
// Add a new tab
mTabbedPane.insertTab(label, icon, comp, tooltip, dst);
Tools.swapVectorPositions(mTabbedPaneMapModules, src, dst);
getMapModuleManager().swapModules(src, dst);
mTabbedPane.setSelectedIndex(dst);
mTabbedPaneSelectionUpdate = true;
// Restore all properties
mTabbedPane.setDisabledIconAt(dst, iconDis);
mTabbedPane.setEnabledAt(dst, enabled);
mTabbedPane.setMnemonicAt(dst, keycode);
mTabbedPane.setDisplayedMnemonicIndexAt(dst, mnemonicLoc);
mTabbedPane.setForegroundAt(dst, fg);
mTabbedPane.setBackgroundAt(dst, bg);
}
//
// Node navigation
//
private class MoveToRootAction extends AbstractAction {
MoveToRootAction(Controller controller) {
super(controller.getResourceString("move_to_root"));
setEnabled(false);
}
public void actionPerformed(ActionEvent event) {
moveToRoot();
}
}
private class ToggleMenubarAction extends AbstractAction implements
MenuItemSelectedListener {
ToggleMenubarAction(Controller controller) {
super(controller.getResourceString("toggle_menubar"));
setEnabled(true);
}
public void actionPerformed(ActionEvent event) {
menubarVisible = !menubarVisible;
setMenubarVisible(menubarVisible);
}
public boolean isSelected(JMenuItem pCheckItem, Action pAction) {
return menubarVisible;
}
}
private class ToggleToolbarAction extends AbstractAction implements
MenuItemSelectedListener {
ToggleToolbarAction(Controller controller) {
super(controller.getResourceString("toggle_toolbar"));
setEnabled(true);
}
public void actionPerformed(ActionEvent event) {
toolbarVisible = !toolbarVisible;
setToolbarVisible(toolbarVisible);
}
public boolean isSelected(JMenuItem pCheckItem, Action pAction) {
logger.info("ToggleToolbar was asked for selectedness.");
return toolbarVisible;
}
}
private class ToggleLeftToolbarAction extends AbstractAction implements
MenuItemSelectedListener {
ToggleLeftToolbarAction(Controller controller) {
super(controller.getResourceString("toggle_left_toolbar"));
setEnabled(true);
}
public void actionPerformed(ActionEvent event) {
leftToolbarVisible = !leftToolbarVisible;
setLeftToolbarVisible(leftToolbarVisible);
}
public boolean isSelected(JMenuItem pCheckItem, Action pAction) {
return leftToolbarVisible;
}
}
protected class ZoomInAction extends AbstractAction {
public ZoomInAction(Controller controller) {
super(controller.getResourceString("zoom_in"));
}
public void actionPerformed(ActionEvent e) {
// logger.info("ZoomInAction actionPerformed");
float currentZoom = getView().getZoom();
for (int i = 0; i < zoomValues.length; i++) {
float val = zoomValues[i];
if (val > currentZoom) {
setZoom(val);
return;
}
}
setZoom(zoomValues[zoomValues.length - 1]);
}
}
protected class ZoomOutAction extends AbstractAction {
public ZoomOutAction(Controller controller) {
super(controller.getResourceString("zoom_out"));
}
public void actionPerformed(ActionEvent e) {
float currentZoom = getView().getZoom();
float lastZoom = zoomValues[0];
for (int i = 0; i < zoomValues.length; i++) {
float val = zoomValues[i];
if (val >= currentZoom) {
setZoom(lastZoom);
return;
}
lastZoom = val;
}
setZoom(lastZoom);
}
}
protected class ShowSelectionAsRectangleAction extends AbstractAction
implements MenuItemSelectedListener {
public ShowSelectionAsRectangleAction(Controller controller) {
super(controller.getResourceString("selection_as_rectangle"));
}
public void actionPerformed(ActionEvent e) {
// logger.info("ShowSelectionAsRectangleAction action Performed");
toggleSelectionAsRectangle();
}
public boolean isSelected(JMenuItem pCheckItem, Action pAction) {
return isSelectionAsRectangle();
}
}
private class ShowAllAttributesAction extends AbstractAction {
public ShowAllAttributesAction() {
super(Resources.getInstance().getResourceString(
"attributes_show_all"));
};
public void actionPerformed(ActionEvent e) {
final MindMap map = getMap();
setAttributeViewType(map);
}
public void setAttributeViewType(final MindMap map) {
final AttributeRegistry attributes = map.getRegistry()
.getAttributes();
if (attributes.getAttributeViewType() != AttributeTableLayoutModel.SHOW_ALL) {
attributes
.setAttributeViewType(AttributeTableLayoutModel.SHOW_ALL);
}
}
}
private class HideAllAttributesAction extends AbstractAction {
public HideAllAttributesAction() {
super(Resources.getInstance().getResourceString(
"attributes_hide_all"));
};
public void actionPerformed(ActionEvent e) {
final MindMap map = getMap();
setAttributeViewType(map);
}
public void setAttributeViewType(final MindMap map) {
final AttributeRegistry attributes = map.getRegistry()
.getAttributes();
if (attributes.getAttributeViewType() != AttributeTableLayoutModel.HIDE_ALL) {
attributes
.setAttributeViewType(AttributeTableLayoutModel.HIDE_ALL);
}
}
}
private class ShowSelectedAttributesAction extends AbstractAction {
public ShowSelectedAttributesAction() {
super(Resources.getInstance().getResourceString(
"attributes_show_selected"));
};
public void actionPerformed(ActionEvent e) {
MindMap map = getMap();
setAttributeViewType(map);
}
void setAttributeViewType(MindMap map) {
final AttributeRegistry attributes = map.getRegistry()
.getAttributes();
if (attributes.getAttributeViewType() != AttributeTableLayoutModel.SHOW_SELECTED) {
attributes
.setAttributeViewType(AttributeTableLayoutModel.SHOW_SELECTED);
}
}
}
//
// Preferences
//
public static Collection getPropertyChangeListeners() {
return Collections.unmodifiableCollection(propertyChangeListeners);
}
public void toggleSelectionAsRectangle() {
if (isSelectionAsRectangle()) {
setProperty(FreeMind.RESOURCE_DRAW_RECTANGLE_FOR_SELECTION,
BooleanProperty.FALSE_VALUE);
} else {
setProperty(FreeMind.RESOURCE_DRAW_RECTANGLE_FOR_SELECTION,
BooleanProperty.TRUE_VALUE);
}
}
private boolean isSelectionAsRectangle() {
return getProperty(FreeMind.RESOURCE_DRAW_RECTANGLE_FOR_SELECTION)
.equalsIgnoreCase(BooleanProperty.TRUE_VALUE);
}
/**
*/
public MindMap getMap() {
return getMapModule().getModel();
}
public static void addPropertyChangeListener(
FreemindPropertyListener listener) {
Controller.propertyChangeListeners.add(listener);
}
/**
* @param listener
* The new listener. All currently available properties are sent
* to the listener after registration. Here, the oldValue
* parameter is set to null.
*/
public static void addPropertyChangeListenerAndPropagate(
FreemindPropertyListener listener) {
Controller.addPropertyChangeListener(listener);
Properties properties = Resources.getInstance().getProperties();
for (Iterator it = properties.keySet().iterator(); it.hasNext();) {
String key = (String) it.next();
listener.propertyChanged(key, properties.getProperty(key), null);
}
}
public static void removePropertyChangeListener(
FreemindPropertyListener listener) {
Controller.propertyChangeListeners.remove(listener);
}
/**
* @author foltin
*
*/
public class PropertyAction extends AbstractAction {
private final Controller controller;
/**
*
*/
public PropertyAction(Controller controller) {
super(controller.getResourceString("property_dialog"));
this.controller = controller;
}
public void actionPerformed(ActionEvent arg0) {
JDialog dialog = new JDialog(getFrame().getJFrame(), true /* modal */);
dialog.setResizable(true);
dialog.setUndecorated(false);
final OptionPanel options = new OptionPanel((FreeMind) getFrame(),
dialog, new OptionPanelFeedback() {
public void writeProperties(Properties props) {
Vector sortedKeys = new Vector();
sortedKeys.addAll(props.keySet());
Collections.sort(sortedKeys);
boolean propertiesChanged = false;
for (Iterator i = sortedKeys.iterator(); i
.hasNext();) {
String key = (String) i.next();
// save only changed keys:
String newProperty = props.getProperty(key);
propertiesChanged = propertiesChanged
|| !newProperty.equals(controller
.getProperty(key));
controller.setProperty(key, newProperty);
}
if (propertiesChanged) {
JOptionPane
.showMessageDialog(
null,
getResourceString("option_changes_may_require_restart"));
controller.getFrame().saveProperties(false);
}
}
});
options.buildPanel();
options.setProperties();
dialog.setTitle("Freemind Properties");
dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
dialog.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent event) {
options.closeWindow();
}
});
Action action = new AbstractAction() {
public void actionPerformed(ActionEvent arg0) {
options.closeWindow();
}
};
Tools.addEscapeActionToDialog(dialog, action);
dialog.setVisible(true);
}
}
private class BackgroundSwatch extends ColorSwatch {
Color getColor() {
return getView().getBackground();
}
}
public class OptionAntialiasAction extends AbstractAction implements
FreemindPropertyListener {
OptionAntialiasAction(Controller controller) {
Controller.addPropertyChangeListener(this);
}
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
changeAntialias(command);
}
/**
*/
public void changeAntialias(String command) {
if (command == null) {
return;
}
if (command.equals("antialias_none")) {
setAntialiasEdges(false);
setAntialiasAll(false);
}
if (command.equals("antialias_edges")) {
setAntialiasEdges(true);
setAntialiasAll(false);
}
if (command.equals("antialias_all")) {
setAntialiasEdges(true);
setAntialiasAll(true);
}
if (getView() != null)
getView().repaint();
}
public void propertyChanged(String propertyName, String newValue,
String oldValue) {
if (propertyName.equals(FreeMindCommon.RESOURCE_ANTIALIAS)) {
changeAntialias(newValue);
}
}
}
private class OptionHTMLExportFoldingAction extends AbstractAction {
OptionHTMLExportFoldingAction(Controller controller) {
}
public void actionPerformed(ActionEvent e) {
setProperty("html_export_folding", e.getActionCommand());
}
}
// switch auto properties for selection mechanism fc, 7.12.2003.
private class OptionSelectionMechanismAction extends AbstractAction
implements FreemindPropertyListener {
Controller c;
OptionSelectionMechanismAction(Controller controller) {
c = controller;
Controller.addPropertyChangeListener(this);
}
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
changeSelection(command);
}
/**
*/
private void changeSelection(String command) {
setProperty("selection_method", command);
// and update the selection method in the NodeMouseMotionListener
c.getNodeMouseMotionListener().updateSelectionMethod();
String statusBarString = c.getResourceString(command);
if (statusBarString != null) // should not happen
c.getFrame().out(statusBarString);
}
public void propertyChanged(String propertyName, String newValue,
String oldValue) {
if (propertyName.equals(FreeMind.RESOURCES_SELECTION_METHOD)) {
changeSelection(newValue);
}
}
}
// open faq url from freeminds page:
private class OpenURLAction extends AbstractAction {
Controller c;
private final String url;
OpenURLAction(Controller controller, String description, String url) {
super(description, new ImageIcon(
controller.getResource("images/Link.png")));
c = controller;
this.url = url;
}
public void actionPerformed(ActionEvent e) {
try {
c.getFrame().openDocument(new URL(url));
} catch (MalformedURLException ex) {
c.errorMessage(c.getResourceString("url_error") + "\n" + ex);
} catch (Exception ex) {
c.errorMessage(ex);
}
}
}
public FilterController getFilterController() {
return mFilterController;
}
public PageFormat getPageFormat() {
return pageFormat;
}
public void setAttributeViewType(MindMap map, String value) {
if (value.equals(AttributeTableLayoutModel.SHOW_SELECTED)) {
((ShowSelectedAttributesAction) showSelectedAttributes)
.setAttributeViewType(map);
} else if (value.equals(AttributeTableLayoutModel.HIDE_ALL)) {
((HideAllAttributesAction) hideAllAttributes)
.setAttributeViewType(map);
} else if (value.equals(AttributeTableLayoutModel.SHOW_ALL)) {
((ShowAllAttributesAction) showAllAttributes)
.setAttributeViewType(map);
}
}
public Object setEdgesRenderingHint(Graphics2D g) {
Object renderingHint = g
.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
(getAntialiasEdges()) ? RenderingHints.VALUE_ANTIALIAS_ON
: RenderingHints.VALUE_ANTIALIAS_OFF);
return renderingHint;
}
public void setTextRenderingHint(Graphics2D g) {
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
(getAntialiasAll()) ? RenderingHints.VALUE_TEXT_ANTIALIAS_ON
: RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
(getAntialiasAll()) ? RenderingHints.VALUE_ANTIALIAS_ON
: RenderingHints.VALUE_ANTIALIAS_OFF);
}
public void addTabbedPane(JTabbedPane pTabbedPane) {
mTabbedPane = pTabbedPane;
mTabbedPaneMapModules = new Vector();
mTabbedPane.addChangeListener(new ChangeListener() {
public synchronized void stateChanged(ChangeEvent pE) {
tabSelectionChanged();
}
});
getMapModuleManager().addListener(new MapModuleChangeObserver() {
public void afterMapModuleChange(MapModule pOldMapModule,
Mode pOldMode, MapModule pNewMapModule, Mode pNewMode) {
int selectedIndex = mTabbedPane.getSelectedIndex();
if (pNewMapModule == null) {
return;
}
// search, if already present:
for (int i = 0; i < mTabbedPaneMapModules.size(); ++i) {
if (mTabbedPaneMapModules.get(i) == pNewMapModule) {
if (selectedIndex != i) {
mTabbedPane.setSelectedIndex(i);
}
return;
}
}
// create new tab:
mTabbedPaneMapModules.add(pNewMapModule);
mTabbedPane.addTab(pNewMapModule.toString(), new JPanel());
mTabbedPane.setSelectedIndex(mTabbedPane.getTabCount() - 1);
}
public void beforeMapModuleChange(MapModule pOldMapModule,
Mode pOldMode, MapModule pNewMapModule, Mode pNewMode) {
}
public boolean isMapModuleChangeAllowed(MapModule pOldMapModule,
Mode pOldMode, MapModule pNewMapModule, Mode pNewMode) {
return true;
}
public void numberOfOpenMapInformation(int pNumber, int pIndex) {
}
public void afterMapClose(MapModule pOldMapModule, Mode pOldMode) {
for (int i = 0; i < mTabbedPaneMapModules.size(); ++i) {
if (mTabbedPaneMapModules.get(i) == pOldMapModule) {
logger.fine("Remove tab:" + i + " with title:"
+ mTabbedPane.getTitleAt(i));
mTabbedPaneSelectionUpdate = false;
mTabbedPane.removeTabAt(i);
mTabbedPaneMapModules.remove(i);
mTabbedPaneSelectionUpdate = true;
tabSelectionChanged();
return;
}
}
}
});
registerMapTitleChangeListener(new MapModuleManager.MapTitleChangeListener() {
public void setMapTitle(String pNewMapTitle, MapModule pMapModule,
MindMap pModel) {
for (int i = 0; i < mTabbedPaneMapModules.size(); ++i) {
if (mTabbedPaneMapModules.get(i) == pMapModule) {
mTabbedPane.setTitleAt(i,
pNewMapTitle + ((pModel.isSaved()) ? "" : "*"));
}
}
}
});
}
private void tabSelectionChanged() {
if (!mTabbedPaneSelectionUpdate)
return;
int selectedIndex = mTabbedPane.getSelectedIndex();
// display nothing on the other tabs:
for (int j = 0; j < mTabbedPane.getTabCount(); j++) {
if (j != selectedIndex)
mTabbedPane.setComponentAt(j, new JPanel());
}
if (selectedIndex < 0) {
// nothing selected. probably, the last map was closed
return;
}
MapModule module = (MapModule) mTabbedPaneMapModules.get(selectedIndex);
logger.fine("Selected index of tab is now: " + selectedIndex
+ " with title:" + module.toString());
if (module != getMapModule()) {
// we have to change the active map actively:
getMapModuleManager().changeToMapModule(module.toString());
}
// mScrollPane could be set invisible by JTabbedPane
frame.getScrollPane().setVisible(true);
mTabbedPane.setComponentAt(selectedIndex, frame.getContentComponent());
// double call, due to mac strangeness.
obtainFocusForSelected();
}
protected void storePageFormat() {
if (pageFormat.getOrientation() == PageFormat.LANDSCAPE) {
setProperty("page_orientation", "landscape");
} else if (pageFormat.getOrientation() == PageFormat.PORTRAIT) {
setProperty("page_orientation", "portrait");
} else if (pageFormat.getOrientation() == PageFormat.REVERSE_LANDSCAPE) {
setProperty("page_orientation", "reverse_landscape");
}
setProperty(PAGE_FORMAT_PROPERTY,
Tools.getPageFormatAsString(pageFormat.getPaper()));
}
}