/** - * Copyright (c) 2013-2016 Angelo ZERR. * 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: * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation */ package tern.eclipse.ide.ui.views; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.text.DocumentEvent; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocumentListener; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.ui.navigator.CommonViewer; import org.eclipse.ui.part.Page; import org.eclipse.ui.views.contentoutline.IContentOutlinePage; import tern.eclipse.ide.core.TernCorePlugin; import tern.eclipse.ide.internal.ui.Trace; import tern.eclipse.ide.internal.ui.views.actions.LinkEditorAction; import tern.eclipse.ide.internal.ui.views.actions.TerminateTernServerAction; import tern.eclipse.ide.ui.utils.EditorUtils; import tern.server.ITernServer; import tern.server.ITernServerListener; import tern.server.protocol.outline.IJSNode; /** * Abstract class for tern outline page. * */ public abstract class AbstractTernContentOutlinePage extends Page implements IContentOutlinePage, ITernServerListener, IDocumentListener { private final AbstractTernOutlineView view; private CommonViewer viewer; // Commons actions private LinkEditorAction toggleLinkingAction; private TerminateTernServerAction terminateAction; private final IProject project; private IDocument currentDocument; private IFile currentFile; public AbstractTernContentOutlinePage(IProject project, AbstractTernOutlineView view) { this.project = project; this.view = view; } @Override public void addSelectionChangedListener(ISelectionChangedListener listener) { this.viewer.addSelectionChangedListener(listener); } @Override public ISelection getSelection() { return this.viewer.getSelection(); } @Override public void removeSelectionChangedListener(ISelectionChangedListener listener) { this.viewer.removePostSelectionChangedListener(listener); } @Override public void setSelection(ISelection selection) { this.viewer.setSelection(selection); } @Override public Control getControl() { return this.viewer != null ? this.viewer.getControl() : null; } @Override public void setFocus() { getControl().setFocus(); } @Override public void createControl(Composite parent) { viewer = new CommonViewer(getViewerId(), parent, SWT.MULTI); viewer.addDoubleClickListener(new IDoubleClickListener() { @Override public void doubleClick(DoubleClickEvent event) { IStructuredSelection selection = (IStructuredSelection) event.getSelection(); if (!selection.isEmpty()) { if (selection.getFirstElement() instanceof IJSNode) { IJSNode node = (IJSNode) selection.getFirstElement(); view.openInEditor(node, true); } } } }); viewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { updateEnabledActions(); IStructuredSelection selection = (IStructuredSelection) event.getSelection(); if (!selection.isEmpty()) { if (selection.getFirstElement() instanceof IJSNode) { IJSNode node = (IJSNode) selection.getFirstElement(); IFile nodeFile = EditorUtils.getFile(node); if (nodeFile == null || nodeFile.equals(getCurrentFile())) { view.openInEditor(node, false); } } } } }); // viewer.setAutoExpandLevel(TreeViewer.ALL_LEVELS); // Actions registerActions(getSite().getActionBars().getToolBarManager()); registerContextMenu(viewer.getControl()); try { IProject project = getProject(); TernCorePlugin.getTernProject(project).addServerListener(this); } catch (CoreException e) { Trace.trace(Trace.SEVERE, "error while getting tern project", e); } updateEnabledActions(); } protected void registerActions(IToolBarManager manager) { this.toggleLinkingAction = new LinkEditorAction(view, getViewer()); manager.add(toggleLinkingAction); this.terminateAction = new TerminateTernServerAction(this); manager.add(terminateAction); } protected void registerContextMenu(Control control) { } public CommonViewer getViewer() { return viewer; } protected void updateEnabledActions() { } @Override public void onStart(ITernServer server) { refreshOutline(); terminateAction.setEnabled(true); } @Override public void onStop(ITernServer server) { terminateAction.setEnabled(false); } @Override public void dispose() { super.dispose(); if (this.currentDocument != null) { currentDocument.removeDocumentListener(this); } try { IProject project = getProject(); TernCorePlugin.getTernProject(project).removeServerListener(this); } catch (CoreException e) { Trace.trace(Trace.SEVERE, "error while getting tern project", e); } } public void setCurrentFile(IFile currentFile) { // Old file/document IFile oldFile = this.currentFile; IDocument oldDocument = this.currentDocument; if (oldDocument != null) { oldDocument.removeDocumentListener(this); } // new file/document this.currentFile = currentFile; this.currentDocument = EditorUtils.getDocument(currentFile); if (currentDocument != null) { currentDocument.addDocumentListener(this); } if (isRefreshOutline(oldFile, currentFile)) { refreshOutline(); } } protected abstract boolean isRefreshOutline(IFile oldFile, IFile newFile); protected abstract String getViewerId(); public final IFile getCurrentFile() { return currentFile; } public IDocument getCurrentDocument() { return currentDocument; } public final IProject getProject() { return project; } public abstract IFile getFile(); /** * Refresh the outline tree in a job. */ public void refreshOutline() { view.refreshOutline(); } @Override public void documentChanged(DocumentEvent event) { refreshOutline(); } @Override public void documentAboutToBeChanged(DocumentEvent event) { } }