OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / sdk / eclipse / plugins / com.android.ide.eclipse.adt / src / com / android / ide / eclipse / adt / internal / editors / ui / tree / PasteAction.java
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Eclipse Public License, Version 1.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.eclipse.org/org/documents/epl-v10.php
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.ide.eclipse.adt.internal.editors.ui.tree;
18
19 import com.android.ide.eclipse.adt.AdtPlugin;
20 import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor;
21 import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
22 import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
23
24 import org.eclipse.jface.action.Action;
25 import org.eclipse.jface.text.BadLocationException;
26 import org.eclipse.swt.dnd.Clipboard;
27 import org.eclipse.swt.dnd.TextTransfer;
28 import org.eclipse.ui.ISharedImages;
29 import org.eclipse.ui.PlatformUI;
30 import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
31 import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
32 import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
33 import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
34 import org.eclipse.wst.xml.core.internal.document.NodeContainer;
35 import org.w3c.dom.Node;
36
37
38 /**
39  * Provides Paste operation for the tree nodes
40  */
41 public class PasteAction extends Action {
42     private UiElementNode mUiNode;
43     private final AndroidXmlEditor mEditor;
44     private final Clipboard mClipboard;
45
46     public PasteAction(AndroidXmlEditor editor, Clipboard clipboard, UiElementNode ui_node) {
47         super("Paste");
48         mEditor = editor;
49         mClipboard = clipboard;
50
51         ISharedImages images = PlatformUI.getWorkbench().getSharedImages();
52         setImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE));
53         setHoverImageDescriptor(images.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE));
54         setDisabledImageDescriptor(
55                 images.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE_DISABLED));
56
57         mUiNode = ui_node;
58     }
59
60     /**
61      * Performs the paste operation.
62      */
63     @Override
64     public void run() {
65         super.run();
66         
67         final String data = (String) mClipboard.getContents(TextTransfer.getInstance());
68         if (data != null) {
69             IStructuredModel model = mEditor.getModelForEdit();
70             try {
71                 IStructuredDocument sse_doc = mEditor.getStructuredDocument();
72                 if (sse_doc != null) {
73                     if (mUiNode.getDescriptor().hasChildren()) {
74                         // This UI Node can have children. The new XML is
75                         // inserted as the first child.
76                         
77                         if (mUiNode.getUiChildren().size() > 0) {
78                             // There's already at least one child, so insert right before it.
79                             Node xml_node = mUiNode.getUiChildren().get(0).getXmlNode();
80                             if (xml_node instanceof IndexedRegion) { // implies xml_node != null
81                                 IndexedRegion region = (IndexedRegion) xml_node;
82                                 sse_doc.replace(region.getStartOffset(), 0, data);
83                                 return; // we're done, no need to try the other cases
84                             }                                
85                         }
86                         
87                         // If there's no first XML node child. Create one by
88                         // inserting at the end of the *start* tag.
89                         Node xml_node = mUiNode.getXmlNode();
90                         if (xml_node instanceof NodeContainer) {
91                             NodeContainer container = (NodeContainer) xml_node;
92                             IStructuredDocumentRegion start_tag =
93                                 container.getStartStructuredDocumentRegion();
94                             if (start_tag != null) {
95                                 sse_doc.replace(start_tag.getEndOffset(), 0, data);
96                                 return; // we're done, no need to try the other case
97                             }
98                         }
99                     }
100                     
101                     // This UI Node doesn't accept children. The new XML is inserted as the
102                     // next sibling. This also serves as a fallback if all the previous
103                     // attempts failed. However, this is not possible if the current node
104                     // has for parent a document -- an XML document can only have one root,
105                     // with no siblings.
106                     if (!(mUiNode.getUiParent() instanceof UiDocumentNode)) {
107                         Node xml_node = mUiNode.getXmlNode();
108                         if (xml_node instanceof IndexedRegion) {
109                             IndexedRegion region = (IndexedRegion) xml_node;
110                             sse_doc.replace(region.getEndOffset(), 0, data);
111                         }
112                     }
113                 }
114
115             } catch (BadLocationException e) {
116                 AdtPlugin.log(e, "ParseAction failed for UI Node %2$s, content '%1$s'", //$NON-NLS-1$
117                         mUiNode.getBreadcrumbTrailDescription(true), data);
118             } finally {
119                 model.releaseFromEdit();
120             }
121         }
122     }
123 }
124