blob: 6674ba9ca929a6008c7e3b528083112303e773b8 [file] [log] [blame]
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Eclipse Public License, Version 1.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.eclipse.org/org/documents/epl-v10.php
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.ide.eclipse.adt.internal.editors.ui.tree;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.xml.core.internal.document.NodeContainer;
import org.w3c.dom.Node;
/**
* Provides Paste operation for the tree nodes
*/
@SuppressWarnings("restriction")
public class PasteAction extends Action {
private UiElementNode mUiNode;
private final AndroidXmlEditor mEditor;
private final Clipboard mClipboard;
public PasteAction(AndroidXmlEditor editor, Clipboard clipboard, UiElementNode ui_node) {
super("Paste");
mEditor = editor;
mClipboard = clipboard;
ISharedImages images = PlatformUI.getWorkbench().getSharedImages();
setImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE));
setHoverImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE));
setDisabledImageDescriptor(
images.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE_DISABLED));
mUiNode = ui_node;
}
/**
* Performs the paste operation.
*/
@Override
public void run() {
super.run();
final String data = (String) mClipboard.getContents(TextTransfer.getInstance());
if (data != null) {
mEditor.wrapEditXmlModel(new Runnable() {
@Override
public void run() {
try {
IStructuredDocument sse_doc = mEditor.getStructuredDocument();
if (sse_doc != null) {
if (mUiNode.getDescriptor().hasChildren()) {
// This UI Node can have children. The new XML is
// inserted as the first child.
if (mUiNode.getUiChildren().size() > 0) {
// There's already at least one child,
// so insert right before it.
Node xml_node = mUiNode.getUiChildren().get(0).getXmlNode();
if (xml_node instanceof IndexedRegion) {
IndexedRegion region = (IndexedRegion) xml_node;
sse_doc.replace(region.getStartOffset(), 0, data);
return; // we're done, no need to try the other cases
}
}
// If there's no first XML node child. Create one by
// inserting at the end of the *start* tag.
Node xml_node = mUiNode.getXmlNode();
if (xml_node instanceof NodeContainer) {
NodeContainer container = (NodeContainer) xml_node;
IStructuredDocumentRegion start_tag =
container.getStartStructuredDocumentRegion();
if (start_tag != null) {
sse_doc.replace(start_tag.getEndOffset(), 0, data);
return; // we're done, no need to try the other case
}
}
}
// This UI Node doesn't accept children. The new XML is inserted as the
// next sibling. This also serves as a fallback if all the previous
// attempts failed. However, this is not possible if the current node
// has for parent a document -- an XML document can only have one root,
// with no siblings.
if (!(mUiNode.getUiParent() instanceof UiDocumentNode)) {
Node xml_node = mUiNode.getXmlNode();
if (xml_node instanceof IndexedRegion) {
IndexedRegion region = (IndexedRegion) xml_node;
sse_doc.replace(region.getEndOffset(), 0, data);
}
}
}
} catch (BadLocationException e) {
AdtPlugin.log(e,
"ParseAction failed for UI Node %2$s, content '%1$s'", //$NON-NLS-1$
mUiNode.getBreadcrumbTrailDescription(true), data);
}
}
});
}
}
}