/******************************************************************************* * Copyright (c) 2004, 2008 John Krasnay and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * John Krasnay - initial API and implementation *******************************************************************************/ package net.sf.vex.action; import java.util.ArrayList; import java.util.List; import net.sf.vex.ToolkitPlugin; import net.sf.vex.css.CSS; import net.sf.vex.css.Styles; import net.sf.vex.dom.Document; import net.sf.vex.dom.DocumentFragment; import net.sf.vex.dom.Element; import net.sf.vex.widget.IVexWidget; /** * Splits the current block element. */ public class SplitAction extends AbstractVexAction { public void run(final IVexWidget vexWidget) { Element element = vexWidget.getCurrentElement(); Styles styles = vexWidget.getStyleSheet().getStyles(element); while (!styles.isBlock()) { element = element.getParent(); styles = vexWidget.getStyleSheet().getStyles(element); } splitElement(vexWidget, element); } /** * Splits the given element. * @param vexWidget IVexWidget containing the document. * @param element Element to be split. */ public static void splitElement(final IVexWidget vexWidget, final Element element) { vexWidget.doWork(new Runnable() { public void run() { long start = 0; if (ToolkitPlugin.getInstance().isDebugging()) { start = System.currentTimeMillis(); } Styles styles = vexWidget.getStyleSheet().getStyles(element); if (styles.getWhiteSpace().equals(CSS.PRE)) { // can't call vexWidget.insertText() or we'll get an infinite loop Document doc = vexWidget.getDocument(); int offset = vexWidget.getCaretOffset(); doc.insertText(offset, "\n"); vexWidget.moveTo(offset + 1); } else { // There may be a number of child elements below the given // element. We cut out the tails of each of these elements // and put them in a list of fragments to be reconstructed when // we clone the element. List children = new ArrayList(); List frags = new ArrayList(); Element child = vexWidget.getCurrentElement(); while (true) { children.add(child); vexWidget.moveTo(child.getEndOffset(), true); frags.add(vexWidget.getSelectedFragment()); vexWidget.deleteSelection(); vexWidget.moveTo(child.getEndOffset() + 1); if (child == element) { break; } child = child.getParent(); } for (int i = children.size() - 1; i >= 0; i--) { child = (Element) children.get(i); DocumentFragment frag = (DocumentFragment) frags.get(i); vexWidget.insertElement((Element) child.clone()); int offset = vexWidget.getCaretOffset(); if (frag != null) { vexWidget.insertFragment(frag); } vexWidget.moveTo(offset); } } if (ToolkitPlugin.getInstance().isDebugging()) { long end = System.currentTimeMillis(); System.out.println("split() took " + (end - start) + "ms"); } } }); } }