| /******************************************************************************* |
| * Copyright (c) 2004, 2007 Mylyn project committers 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 |
| *******************************************************************************/ |
| /* |
| * Created on Apr 1, 2005 |
| */ |
| package org.eclipse.mylyn.internal.pde.ui; |
| |
| import java.util.Locale; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.jface.text.IDocument; |
| import org.eclipse.jface.text.TextSelection; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.mylyn.commons.core.StatusHandler; |
| import org.eclipse.mylyn.internal.ide.ui.XmlNodeHelper; |
| import org.eclipse.mylyn.monitor.ui.AbstractUserInteractionMonitor; |
| import org.eclipse.pde.core.plugin.IPluginModelBase; |
| import org.eclipse.pde.core.plugin.IPluginObject; |
| import org.eclipse.pde.internal.core.plugin.ImportObject; |
| import org.eclipse.pde.internal.core.text.IDocumentAttribute; |
| import org.eclipse.pde.internal.core.text.IDocumentNode; |
| import org.eclipse.pde.internal.core.text.plugin.PluginModel; |
| import org.eclipse.pde.internal.core.text.plugin.PluginObjectNode; |
| import org.eclipse.pde.internal.ui.editor.plugin.ManifestEditor; |
| import org.eclipse.pde.internal.ui.editor.plugin.ManifestSourcePage; |
| import org.eclipse.ui.IEditorInput; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.part.FileEditorInput; |
| |
| /** |
| * @author Shawn Minto |
| * @author Mik Kersten |
| */ |
| public class PdeEditingMonitor extends AbstractUserInteractionMonitor { |
| |
| public PdeEditingMonitor() { |
| super(); |
| } |
| |
| @Override |
| protected void handleWorkbenchPartSelection(IWorkbenchPart part, ISelection selection, boolean contributeToContext) { |
| if (part instanceof ManifestEditor) { |
| TextSelection textSelection = null; |
| IEditorInput in = null; |
| |
| // assume that we are editing an xml file due to the editor used |
| // this is the plugin.xml editor |
| |
| ManifestEditor editor = (ManifestEditor) part; |
| |
| // fix bug when user is looking in the cvs repository since the |
| // input |
| // is not a FileEditorInput |
| if (!(editor.getEditorInput() instanceof FileEditorInput)) { |
| return; |
| } |
| |
| // make sure that the selection is a text selection |
| if (!(editor.getSelection() instanceof TextSelection || editor.getSelection() instanceof StructuredSelection)) { |
| return; |
| } else if (editor.getSelection() instanceof StructuredSelection) { |
| StructuredSelection s = (StructuredSelection) editor.getSelection(); |
| if (s.getFirstElement() instanceof PluginObjectNode) { |
| PluginObjectNode n = (PluginObjectNode) s.getFirstElement(); |
| textSelection = new TextSelection(n.getOffset(), n.getLength()); |
| } else if (s.getFirstElement() instanceof ImportObject) { |
| ImportObject io = (ImportObject) s.getFirstElement(); |
| if (io.getImport() instanceof PluginObjectNode) { |
| PluginObjectNode n = (PluginObjectNode) io.getImport(); |
| textSelection = new TextSelection(n.getOffset(), n.getLength()); |
| } |
| } else { |
| return; |
| } |
| } else { |
| // get the selection and the editor input |
| textSelection = (TextSelection) editor.getSelection(); |
| } |
| in = editor.getEditorInput(); |
| |
| // check if we have a text selection |
| if (textSelection != null) { |
| try { |
| |
| // get the node for the selection |
| int offset = textSelection.getOffset(); |
| PluginObjectNode node = getNode(editor, offset, false); |
| |
| if (node != null) { |
| FileEditorInput fei = (FileEditorInput) in; |
| |
| // fix a bug when there is a selection and the editor |
| // input is the manifest.mf file |
| // not the plugin.xml |
| if (fei.getFile().getFullPath().toString().toLowerCase(Locale.ENGLISH).endsWith("/manifest.mf")) { |
| return; |
| } |
| |
| String nodeString = getStringOfNode(node); |
| if (nodeString == null) { |
| return; |
| } |
| |
| // create the helper to get the handle for the node |
| XmlNodeHelper xnode = new XmlNodeHelper(fei.getFile().getFullPath().toString(), |
| nodeString.hashCode()); |
| |
| // get the name for the node |
| // String name = node.getXMLAttributeValue("name"); |
| // if (name == null) |
| // name = node.getXMLTagName(); |
| super.handleElementSelection(part, xnode, contributeToContext); |
| } |
| } catch (Exception e) { |
| StatusHandler.log(new Status(IStatus.ERROR, PdeUiBridgePlugin.ID_PLUGIN, |
| "Could not resolve selection", e)); |
| } |
| } |
| } |
| } |
| |
| public static String getStringOfNode(IDocumentNode node) { |
| if (node == null) { |
| return null; |
| } |
| String s = node.getXMLTagName(); |
| for (IDocumentAttribute a : node.getNodeAttributes()) { |
| s += a.getAttributeName() + "=" + a.getAttributeValue(); |
| } |
| return s; |
| } |
| |
| /** |
| * COPIED FROM ManifestSourcePage - from a getRangeElement body |
| */ |
| public static PluginObjectNode getNode(ManifestEditor editor, int offset, boolean hashCode) { |
| ManifestSourcePage page = (ManifestSourcePage) editor.findPage("plugin-context"); |
| if (page != null) { |
| IPluginModelBase model = (IPluginModelBase) page.getInputContext().getModel(); |
| PluginObjectNode node = (PluginObjectNode) PdeEditingMonitor.findNode(model.getPluginBase().getLibraries(), |
| offset, hashCode); |
| if (node == null) { |
| node = (PluginObjectNode) PdeEditingMonitor.findNode(model.getPluginBase().getImports(), offset, |
| hashCode); |
| } |
| if (node == null) { |
| node = (PluginObjectNode) PdeEditingMonitor.findNode(model.getPluginBase().getExtensionPoints(), |
| offset, hashCode); |
| } |
| if (node == null) { |
| node = (PluginObjectNode) PdeEditingMonitor.findNode(model.getPluginBase().getExtensions(), offset, |
| hashCode); |
| } |
| if (node == null) { |
| node = (PluginObjectNode) PdeEditingMonitor.findNode(new IPluginObject[] { model.getPluginBase() }, |
| offset, hashCode); |
| } |
| return node; |
| } |
| return null; |
| } |
| |
| public static PluginObjectNode getNode(IDocument d, IFile f, int num, boolean hashCode) throws CoreException { |
| PluginModel model = new PluginModel(d, true); |
| model.setUnderlyingResource(f); |
| if (!model.isLoaded()) { |
| model.load(); |
| model.setEnabled(true); |
| } |
| |
| PluginObjectNode node = (PluginObjectNode) PdeEditingMonitor.findNode(model.getPluginBase().getLibraries(), |
| num, hashCode); |
| if (node == null) { |
| node = (PluginObjectNode) PdeEditingMonitor.findNode(model.getPluginBase().getImports(), num, hashCode); |
| } |
| if (node == null) { |
| node = (PluginObjectNode) PdeEditingMonitor.findNode(model.getPluginBase().getExtensionPoints(), num, |
| hashCode); |
| } |
| if (node == null) { |
| node = (PluginObjectNode) PdeEditingMonitor.findNode(model.getPluginBase().getExtensions(), num, hashCode); |
| } |
| if (node == null) { |
| node = (PluginObjectNode) PdeEditingMonitor.findNode(new IPluginObject[] { model.getPluginBase() }, num, |
| hashCode); |
| } |
| return node; |
| } |
| |
| /** |
| * COPIED FROM ManifestSourcePage |
| */ |
| private static IDocumentNode findNode(IPluginObject[] nodes, int offset, boolean hashCode) { |
| for (IPluginObject element : nodes) { |
| IDocumentNode node = (IDocumentNode) element; |
| IDocumentNode[] children = node.getChildNodes(); |
| |
| // changed region - added to check the children to make it work |
| // properly |
| IDocumentNode node2 = null; |
| if (children.length > 0) { |
| node2 = PdeEditingMonitor.findNode(children, offset, hashCode); |
| // end changed region |
| } |
| |
| if (node2 != null && node2 instanceof IPluginObject) { |
| return node2; |
| } |
| |
| if (!hashCode) { |
| if (offset >= node.getOffset() && offset < node.getOffset() + node.getLength()) { |
| return node; |
| } |
| } else { |
| if (getStringOfNode(node).hashCode() == offset) { |
| return node; |
| } |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * Copy of previous, taking different arguments |
| */ |
| private static IDocumentNode findNode(IDocumentNode[] nodes, int offset, boolean hashCode) { |
| for (IDocumentNode node : nodes) { |
| IDocumentNode[] children = node.getChildNodes(); |
| IDocumentNode node2 = null; |
| if (children.length > 0) { |
| node2 = PdeEditingMonitor.findNode(children, offset, hashCode); |
| } |
| if (node2 != null) { |
| return node2; |
| } |
| |
| if (!hashCode) { |
| if (offset >= node.getOffset() && offset < node.getOffset() + node.getLength()) { |
| return node; |
| } |
| } else { |
| if (getStringOfNode(node).hashCode() == offset) { |
| return node; |
| } |
| } |
| } |
| return null; |
| } |
| } |
| |
| // XXX used if we support the xmen editor |
| // if (part instanceof XMLTextEditor) { |
| // XMLTextEditor editor = (XMLTextEditor)part; |
| // TextSelection textSelection = |
| // (TextSelection)editor.getSelectionProvider().getSelection(); |
| // if (textSelection != null) { |
| // |
| // try{ |
| // // get the model for the xml elements |
| // XMLReconciler rec = editor.getModel(); |
| // |
| // int start = textSelection.getStartLine(); |
| // int end = textSelection.getEndLine(); |
| // |
| // // get the node that was selected |
| // XMLNode node = rec.getNodeFromLine(start); |
| // |
| // ContextCorePlugin.getTaskscapeManager().handleElementSelected( |
| // node.getHandle(), node.getCanName(), |
| // IDegreeOfInterest.Value.Selections, |
| // ITaskscapeNode.Kind.XML); |
| // |
| // }catch(Exception e){ |
| // //handle properly |
| // } |
| // } |