/*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 05.05.2004
*
* To change the template for this generated file go to
* Window>Preferences>Java>Code Generation>Code and Comments
*/
package freemind.modes.mindmapmode.actions;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.Vector;
import java.util.regex.Pattern;
import javax.swing.AbstractAction;
import javax.swing.JOptionPane;
import freemind.common.OptionalDontShowMeAgainDialog;
import freemind.controller.actions.generated.instance.EditNodeAction;
import freemind.controller.actions.generated.instance.XmlAction;
import freemind.main.FreeMind;
import freemind.main.HtmlTools;
import freemind.main.Tools;
import freemind.modes.MindMapNode;
import freemind.modes.NodeAdapter;
import freemind.modes.mindmapmode.MindMapController;
import freemind.modes.mindmapmode.actions.xml.ActionPair;
import freemind.modes.mindmapmode.actions.xml.ActorXml;
import freemind.view.mindmapview.EditNodeBase;
import freemind.view.mindmapview.EditNodeDialog;
import freemind.view.mindmapview.EditNodeExternalApplication;
import freemind.view.mindmapview.EditNodeTextField;
import freemind.view.mindmapview.EditNodeWYSIWYG;
import freemind.view.mindmapview.MapView;
import freemind.view.mindmapview.NodeView;
//
//Node editing
//
public class EditAction extends AbstractAction implements ActorXml {
private static final Pattern HTML_HEAD = Pattern.compile(
"\\s*<head>.*</head>", Pattern.DOTALL);
private final MindMapController mMindMapController;
private EditNodeBase mCurrentEditDialog = null;
public EditAction(MindMapController modeController) {
super(modeController.getText("edit_node"));
this.mMindMapController = modeController;
this.mMindMapController.getActionFactory().registerActor(this,
getDoActionClass());
}
public void actionPerformed(ActionEvent arg0) {
MindMapNode selected = this.mMindMapController.getSelected();
this.mMindMapController.edit(null, false, false);
}
/*
* (non-Javadoc)
*
* @see
* freemind.controller.actions.ActorXml#act(freemind.controller.actions.
* generated.instance.XmlAction)
*/
public void act(XmlAction action) {
EditNodeAction editAction = (EditNodeAction) action;
NodeAdapter node = this.mMindMapController.getNodeFromID(editAction
.getNode());
if (!node.toString().equals(editAction.getText())) {
node.setUserObject(editAction.getText());
this.mMindMapController.nodeChanged(node);
}
}
/*
* (non-Javadoc)
*
* @see freemind.controller.actions.ActorXml#getDoActionClass()
*/
public Class getDoActionClass() {
return EditNodeAction.class;
}
// edit begins with home/end or typing (PN 6.2)
public void edit(KeyEvent e, boolean addNew, boolean editLong) {
NodeView selectedNodeView = mMindMapController.getView().getSelected();
if (selectedNodeView != null) {
if (e == null || !addNew) {
edit(selectedNodeView, selectedNodeView, e, false, false,
editLong);
} else if (!mMindMapController.isBlocked()) {
mMindMapController.addNew(mMindMapController.getSelected(),
MindMapController.NEW_SIBLING_BEHIND, e);
}
if (e != null) {
e.consume();
}
}
}
public void edit(final NodeView node, final NodeView prevSelected,
final KeyEvent firstEvent, final boolean isNewNode,
final boolean parentFolded, final boolean editLong) {
if (node == null) {
return;
}
final MapView map = node.getMap();
map.validate();
map.invalidate();
stopEditing();
// EditNodeBase.closeEdit();
mMindMapController.setBlocked(true); // locally "modal" stated
String text = node.getModel().toString();
String htmlEditingOption = mMindMapController.getController()
.getProperty("html_editing_option");
boolean isHtmlNode = HtmlTools.isHtmlNode(text);
boolean isLongNode = node.getIsLong();
// do we need a decision if plain or HTML editing?
String useRichTextInNewLongNodes = (isHtmlNode) ? "true" : "false";
// if the node is not already html, we ask if rich text or plain text
// edit.
if (!isHtmlNode && !isLongNode && editLong) {
// ask user:
int showResult = new OptionalDontShowMeAgainDialog(
mMindMapController.getFrame().getJFrame(),
mMindMapController.getSelectedView(),
"edit.edit_rich_text",
"edit.decision",
mMindMapController,
new OptionalDontShowMeAgainDialog.StandardPropertyHandler(
mMindMapController.getController(),
FreeMind.RESOURCES_REMIND_USE_RICH_TEXT_IN_NEW_LONG_NODES),
OptionalDontShowMeAgainDialog.BOTH_OK_AND_CANCEL_OPTIONS_ARE_STORED)
.show().getResult();
useRichTextInNewLongNodes = (showResult == JOptionPane.OK_OPTION) ? "true"
: "false";
}
// useRichTextInNewLongNodes =
// c.getController().getProperty("use_rich_text_in_new_long_nodes");
boolean editHtml = isHtmlNode
|| (editLong && Tools.safeEquals(useRichTextInNewLongNodes,
"true"));
boolean editInternalWysiwyg = editHtml
&& Tools.safeEquals(htmlEditingOption, "internal-wysiwyg");
boolean editExternal = editHtml
&& Tools.safeEquals(htmlEditingOption, "external");
if (editHtml && !isHtmlNode) {
text = HtmlTools.plainToHTML(text);
}
if (editInternalWysiwyg) {
EditNodeWYSIWYG editNodeWYSIWYG = new EditNodeWYSIWYG(node, text,
firstEvent, mMindMapController,
new EditNodeBase.EditControl() {
public void cancel() {
mMindMapController.setBlocked(false);
mCurrentEditDialog = null;
mMindMapController.getController()
.obtainFocusForSelected();
}
public void ok(String newText) {
setHtmlText(node, newText);
cancel();
}
public void split(String newText, int position) {
mMindMapController.splitNode(node.getModel(),
position, newText);
cancel();
}
}); // focus fix
mCurrentEditDialog = editNodeWYSIWYG;
editNodeWYSIWYG.show();
return;
}
if (editExternal) {
EditNodeExternalApplication editNodeExternalApplication = new EditNodeExternalApplication(
node, text, firstEvent, mMindMapController,
new EditNodeBase.EditControl() {
public void cancel() {
mMindMapController.setBlocked(false);
mCurrentEditDialog = null;
mMindMapController.getController()
.obtainFocusForSelected();
}
public void ok(String newText) {
setHtmlText(node, newText);
cancel();
}
public void split(String newText, int position) {
mMindMapController.splitNode(node.getModel(),
position, newText);
cancel();
}
}); // focus fix
mCurrentEditDialog = editNodeExternalApplication;
editNodeExternalApplication.show();
// We come here before quitting the editor window.
return;
}
if (isLongNode || editLong) {
EditNodeDialog nodeEditDialog = new EditNodeDialog(node, text,
firstEvent, mMindMapController,
new EditNodeBase.EditControl() {
public void cancel() {
mMindMapController.setBlocked(false);
mCurrentEditDialog = null;
mMindMapController.getController()
.obtainFocusForSelected(); // focus fix
}
public void ok(String newText) {
setNodeText(node.getModel(), newText);
cancel();
}
public void split(String newText, int position) {
mMindMapController.splitNode(node.getModel(),
position, newText);
cancel();
}
});
mCurrentEditDialog = nodeEditDialog;
nodeEditDialog.show();
return;
}
// inline editing:
EditNodeTextField textfield = new EditNodeTextField(node, text,
firstEvent, mMindMapController, new EditNodeBase.EditControl() {
public void cancel() {
if (isNewNode) { // delete also the node and set focus
// to the parent
mMindMapController.getView()
.selectAsTheOnlyOneSelected(node);
Vector nodeList = new Vector();
nodeList.add(node.getModel());
mMindMapController.cut(nodeList);
mMindMapController.select(prevSelected);
// include max level for navigation
if (parentFolded) {
mMindMapController.setFolded(
prevSelected.getModel(), true);
}
}
endEdit();
}
public void ok(String newText) {
setNodeText(node.getModel(), newText);
endEdit();
}
private void endEdit() {
mMindMapController.obtainFocusForSelected();
mMindMapController.setBlocked(false);
mCurrentEditDialog = null;
}
public void split(String newText, int position) {
}
});
mCurrentEditDialog = textfield;
textfield.show();
}
public void setNodeText(MindMapNode selected, String newText) {
String oldText = selected.toString();
EditNodeAction EditAction = new EditNodeAction();
EditAction.setNode(mMindMapController.getNodeID(selected));
EditAction.setText(newText);
EditNodeAction undoEditAction = new EditNodeAction();
undoEditAction.setNode(mMindMapController.getNodeID(selected));
undoEditAction.setText(oldText);
mMindMapController.doTransaction(
mMindMapController.getText("edit_node"),
new ActionPair(EditAction, undoEditAction));
}
protected MindMapController getMindMapController() {
return mMindMapController;
}
private void setHtmlText(final NodeView node, String newText) {
final String body = HTML_HEAD.matcher(newText).replaceFirst("");
setNodeText(node.getModel(), body);
}
public void stopEditing() {
if (mCurrentEditDialog != null) {
// there was previous editing.
mCurrentEditDialog.closeEdit();
mCurrentEditDialog = null;
}
}
}