org.eclipse.mylyn.internal.pde.ui.PdeUiBridge.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.mylyn.internal.pde.ui.PdeUiBridge.java

Source

/*******************************************************************************
 * 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;
    }
}