/* * Freeplane - mind map editor * Copyright (C) 2008 Joerg Mueller, Daniel Polansky, Christian Foltin, Dimitry Polivaev * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.freeplane.features.text.mindmapmode; import java.awt.event.ActionEvent; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.util.Collection; import javax.swing.text.BadLocationException; import javax.swing.text.Element; import javax.swing.text.html.HTMLDocument; import javax.swing.text.html.HTMLEditorKit; import org.freeplane.core.ui.AFreeplaneAction; import org.freeplane.core.util.FixedHTMLWriter; import org.freeplane.core.util.LogUtils; import org.freeplane.features.map.NodeModel; import org.freeplane.features.map.mindmapmode.MMapController; import org.freeplane.features.mode.Controller; import org.freeplane.features.mode.ModeController; import org.freeplane.features.nodestyle.NodeStyleController; import org.freeplane.features.nodestyle.mindmapmode.MNodeStyleController; import org.freeplane.features.text.TextController; /** * @author Dimitry Polivaev */ public class SplitNode extends AFreeplaneAction { /** * */ private static final long serialVersionUID = 1L; /** * */ public SplitNode() { super("SplitNode"); } /* * (non-Javadoc) * @see freeplane.extensions.NodeHook#invoke(freeplane.modes.MindMapNode, * java.util.List) */ public void actionPerformed(final ActionEvent e) { final Collection<NodeModel> list = Controller.getCurrentModeController().getMapController().getSelectedNodes(); for (NodeModel next : list) { splitNode(next); } } private Element getParentElement(final HTMLDocument doc) { final Element htmlRoot = doc.getDefaultRootElement(); Element parentCandidate = htmlRoot.getElement(htmlRoot.getElementCount() - 1); do { if (parentCandidate.getElementCount() > 1) { return parentCandidate; } parentCandidate = parentCandidate.getElement(0); } while (!(parentCandidate.isLeaf() || parentCandidate.getName().equalsIgnoreCase("p-implied"))); return null; } private void splitNode(final NodeModel node) { if (node.isRoot()) { return; } final String text = node.getText(); final String[] parts = splitNode(text); if (parts == null || parts.length == 1) { return; } final ModeController c = Controller.getCurrentModeController(); int firstPartNumber = 0; while (parts[firstPartNumber] == null) { firstPartNumber++; } ((MTextController) TextController.getController()).setNodeText(node, parts[firstPartNumber]); final NodeModel parent = node.getParentNode(); final int nodePosition = parent.getChildPosition(node) + 1; for (int i = parts.length - 1; i > firstPartNumber; i--) { final MMapController mapController = (MMapController) c.getMapController(); final NodeModel lowerNode = mapController.addNewNode(parent, nodePosition, node.isLeft()); final String part = parts[i]; if (part == null) { continue; } ((MTextController) TextController.getController()).setNodeText(lowerNode, part); final MNodeStyleController nodeStyleController = (MNodeStyleController) NodeStyleController .getController(); nodeStyleController.copyStyle(node, lowerNode); mapController.setFolded(lowerNode, !lowerNode.isFolded()); } } private String[] splitNode(final String text) { if (text.startsWith("<html>")) { String[] parts = null; final HTMLEditorKit kit = new HTMLEditorKit(); final HTMLDocument doc = new HTMLDocument(); final StringReader buf = new StringReader(text); try { kit.read(buf, doc, 0); final Element parent = getParentElement(doc); if (parent == null) { return null; } final int elementCount = parent.getElementCount(); int notEmptyElementCount = 0; parts = new String[elementCount]; for (int i = 0; i < elementCount; i++) { final Element current = parent.getElement(i); final int start = current.getStartOffset(); final int end = current.getEndOffset(); final String paragraphText = doc.getText(start, end - start).trim(); if (paragraphText.length() > 0) { final StringWriter out = new StringWriter(); new FixedHTMLWriter(out, doc, start, end - start).write(); final String string = out.toString(); if (!string.equals("")) { parts[i] = string; notEmptyElementCount++; } else { parts[i] = null; } } } if (notEmptyElementCount <= 1) { return null; } } catch (final IOException e) { LogUtils.severe(e); } catch (final BadLocationException e) { LogUtils.severe(e); } return parts; } return text.split("\n"); } }