Java tutorial
/******************************************************************************* * Copyright (c) 2004, 2008 Tasktop Technologies 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: * Tasktop Technologies - initial API and implementation *******************************************************************************/ package org.eclipse.mylyn.internal.pde.ui; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.eclipse.core.internal.resources.Workspace; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.jface.text.TextSelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ITreeViewerListener; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TreeExpansionEvent; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.mylyn.commons.core.StatusHandler; import org.eclipse.mylyn.context.core.IInteractionElement; import org.eclipse.mylyn.context.ui.AbstractContextUiBridge; import org.eclipse.pde.internal.core.text.plugin.PluginObjectNode; import org.eclipse.pde.internal.ui.editor.FormOutlinePage; import org.eclipse.pde.internal.ui.editor.ISortableContentOutlinePage; import org.eclipse.pde.internal.ui.editor.PDEFormEditor; import org.eclipse.pde.internal.ui.editor.PDESourcePage; import org.eclipse.pde.internal.ui.editor.SourceOutlinePage; import org.eclipse.pde.internal.ui.editor.plugin.ManifestEditor; import org.eclipse.pde.internal.ui.editor.plugin.PluginInputContext; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorReference; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.forms.editor.FormEditor; import org.eclipse.ui.ide.IDE; import org.eclipse.ui.texteditor.AbstractTextEditor; /** * @author Mik Kersten * @author Shawn Minto */ public class PdeUiBridge extends AbstractContextUiBridge { private final TreeViewerListener treeSelectionChangedListener; public PdeUiBridge() { treeSelectionChangedListener = new TreeViewerListener(); } /** * @see org.eclipse.mylyn.context.ui.AbstractContextUiBridge#open(org.eclipse.mylyn.context.core.IInteractionElement) */ @Override public void open(IInteractionElement node) { // get the handle of the node String handle = node.getHandleIdentifier(); int first = handle.indexOf(";"); //$NON-NLS-1$ String filename = ""; //$NON-NLS-1$ if (first == -1) { filename = handle; } else { filename = handle.substring(0, first); } try { // get the file IPath path = new Path(filename); IFile f = (IFile) ((Workspace) ResourcesPlugin.getWorkspace()).newResource(path, IResource.FILE); // open the xml file looking at the proper line IEditorPart editor = openInEditor(f, true); // if the editor is null, we had a problem and should return if (editor == null) { StatusHandler.log(new Status(IStatus.WARNING, PdeUiBridgePlugin.ID_PLUGIN, "Unable to open editor for file: " + filename)); //$NON-NLS-1$ return; } // get the contents and create a new document so that we can get // the offsets to highlight // String content = XmlNodeHelper.getContents(f.getContents()); // // IDocument d = new Document(content); // if(first != -1){ // int start = Integer.parseInt(handle.substring(first + 1)); // // // get the offsets for the element // int startOffset = d.getLineOffset(start); // int length = 0; // // // set the selection if the selection provider is not null // ISelectionProvider selectionProvider = // editor.getEditorSite().getSelectionProvider(); // if(selectionProvider != null) // selectionProvider.setSelection(new TextSelection(startOffset, // length)); // } } catch (Exception e) { // ContextCorePlugin.log(e, "ERROR OPENING XML EDITOR\n" + // e.getMessage()); } } /** * Open a file in the appropriate editor * * @param file * The IFile to open * @param activate * Whether to activate the editor or not * @return The IEditorPart that the file opened in * @throws PartInitException */ private IEditorPart openInEditor(IFile file, boolean activate) throws PartInitException { if (file != null) { IWorkbenchPage p = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); if (p != null && file.exists()) { IEditorPart editorPart = IDE.openEditor(p, file, activate); // initializeHighlightRange(editorPart); return editorPart; } } return null; } @Override public void close(IInteractionElement node) { IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); if (page != null) { IEditorReference[] references = page.getEditorReferences(); for (IEditorReference reference : references) { IEditorPart part = reference.getEditor(false); if (part != null) { // HACK: find better way to get the filename other than the tooltip if (("/" + part.getTitleToolTip()).equals(node.getHandleIdentifier())) { //$NON-NLS-1$ if (part instanceof FormEditor) { ((FormEditor) part).close(true); } else if (part instanceof AbstractTextEditor) { ((AbstractTextEditor) part).close(true); } } } } } } @Override public boolean acceptsEditor(IEditorPart editorPart) { return editorPart instanceof ManifestEditor; } /** * HACK: use a lot of reflection to get the TreeViewer */ @Override public List<TreeViewer> getContentOutlineViewers(IEditorPart editor) { if (editor instanceof PDEFormEditor) { PDESourcePage sp = null; List<TreeViewer> viewers = new ArrayList<TreeViewer>(2); if ((sp = (PDESourcePage) ((PDEFormEditor) editor).findPage(PluginInputContext.CONTEXT_ID)) != null) { ISortableContentOutlinePage page = sp.getContentOutline(); if (page != null && page.getControl() != null) { try { if (page instanceof SourceOutlinePage) { // get the tree viewer for the outline Class<?> clazz2 = page.getClass(); Field field2 = clazz2.getDeclaredField("viewer"); //$NON-NLS-1$ field2.setAccessible(true); Object f2 = field2.get(page); if (f2 != null && f2 instanceof TreeViewer) { viewers.add((TreeViewer) f2); } } } catch (Exception e) { StatusHandler.log(new Status(IStatus.ERROR, PdeUiBridgePlugin.ID_PLUGIN, "Failed to get tree viewers", e)); //$NON-NLS-1$ return null; } } } try { // get the current page of the outline Class<?> clazz = PDEFormEditor.class; Field field = null; try { field = clazz.getDeclaredField("formOutline"); //$NON-NLS-1$ } catch (NoSuchFieldException e) { field = clazz.getDeclaredField("fFormOutline"); //$NON-NLS-1$ } field.setAccessible(true); Object f = field.get(editor); if (f != null && f instanceof FormOutlinePage) { // get the tree viewer for the outline Class<?> clazz2 = FormOutlinePage.class; Field field2 = null; try { field2 = clazz2.getDeclaredField("treeViewer"); //$NON-NLS-1$ } catch (NoSuchFieldException e) { field2 = clazz2.getDeclaredField("fTreeViewer"); //$NON-NLS-1$ } field2.setAccessible(true); Object f2 = field2.get(f); if (f2 != null && f2 instanceof TreeViewer) { TreeViewer treeViewer = (TreeViewer) f2; viewers.add(treeViewer); } } } catch (Exception e) { StatusHandler.log( new Status(IStatus.ERROR, PdeUiBridgePlugin.ID_PLUGIN, "Could not get PDE outline", e)); //$NON-NLS-1$ return Collections.emptyList(); } // add a listener so that when the selection changes, the view is // refreshed to attempt to keep the ui model the same as the // taskscape one for (TreeViewer viewer : viewers) { viewer.addSelectionChangedListener(treeSelectionChangedListener); viewer.addTreeListener(treeSelectionChangedListener); } return viewers; } return Collections.emptyList(); } public void refreshOutline(Object element, boolean updateLabels, boolean setSelection) { IEditorPart editorPart = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() .getActiveEditor(); List<TreeViewer> treeViewers = getContentOutlineViewers(editorPart); for (TreeViewer treeViewer : treeViewers) { if (treeViewer != null) { if (element == null) { treeViewer.getControl().setRedraw(false); treeViewer.refresh(true); treeViewer.getControl().setRedraw(true); treeViewer.expandAll(); } else if (element instanceof PluginObjectNode) { treeViewer.getControl().setRedraw(false); treeViewer.refresh(element, true); treeViewer.getControl().setRedraw(true); treeViewer.expandAll(); } } } } /** * Class to listen to the tree views to attempt to refresh them more frequently to keep the ui model consistant with * the user selections * * @author Shawn Minto */ private class TreeViewerListener implements ISelectionChangedListener, ITreeViewerListener { public void selectionChanged(SelectionChangedEvent event) { Object o = event.getSource(); if (o instanceof TreeViewer) { ((TreeViewer) o).refresh(); ((TreeViewer) o).expandAll(); } } public void treeCollapsed(TreeExpansionEvent event) { Object o = event.getSource(); if (o instanceof TreeViewer) { ((TreeViewer) o).refresh(); } } public void treeExpanded(TreeExpansionEvent event) { Object o = event.getSource(); if (o instanceof TreeViewer) { ((TreeViewer) o).refresh(); } } } @Override public Object getObjectForTextSelection(TextSelection selection, IEditorPart editor) { return null; } @Override public IInteractionElement getElement(IEditorInput input) { return null; } @Override public String getContentType() { return PdeStructureBridge.CONTENT_TYPE; } }