blob: df4811cd13d4d3e32334a0f2536e1f5dc29c0394 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2018 IBM Corporation 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
*
*******************************************************************************/
package org.eclipse.dltk.internal.ui.search;
import org.eclipse.core.resources.IFile;
import org.eclipse.dltk.core.IExternalSourceModule;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.internal.core.SourceModule;
import org.eclipse.dltk.internal.ui.editor.EditorUtility;
import org.eclipse.dltk.internal.ui.editor.ExternalStorageEditorInput;
import org.eclipse.dltk.ui.DLTKUILanguageManager;
import org.eclipse.dltk.ui.DLTKUIPlugin;
import org.eclipse.dltk.ui.IDLTKUILanguageToolkit;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.search.ui.NewSearchUI;
import org.eclipse.search.ui.text.Match;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IEditorRegistry;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IPartService;
import org.eclipse.ui.IReusableEditor;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.FileEditorInput;
public class DLTKSearchEditorOpener {
private static class ReusedEditorWatcher implements IPartListener {
private IEditorPart fReusedEditor;
private IPartService fPartService;
public ReusedEditorWatcher() {
fReusedEditor = null;
fPartService = null;
}
public IEditorPart getReusedEditor() {
return fReusedEditor;
}
public void initialize(IEditorPart editor) {
if (fReusedEditor != null) {
fPartService.removePartListener(this);
}
fReusedEditor = editor;
if (editor != null) {
fPartService = editor.getSite().getWorkbenchWindow()
.getPartService();
fPartService.addPartListener(this);
} else {
fPartService = null;
}
}
@Override
public void partOpened(IWorkbenchPart part) {
}
@Override
public void partDeactivated(IWorkbenchPart part) {
}
@Override
public void partClosed(IWorkbenchPart part) {
if (part == fReusedEditor) {
initialize(null);
}
}
@Override
public void partActivated(IWorkbenchPart part) {
}
@Override
public void partBroughtToTop(IWorkbenchPart part) {
}
}
private ReusedEditorWatcher fReusedEditorWatcher;
public IEditorPart openElement(Object element)
throws PartInitException, ModelException {
IWorkbenchPage wbPage = DLTKUIPlugin.getActivePage();
final IEditorPart editor;
if (NewSearchUI.reuseEditor())
editor = showWithReuse(element, wbPage);
else
editor = showWithoutReuse(element, wbPage);
if (element instanceof IModelElement)
EditorUtility.revealInEditor(editor, (IModelElement) element);
return editor;
}
public IEditorPart openMatch(Match match)
throws PartInitException, ModelException {
Object element = getElementToOpen(match);
return openElement(element);
}
protected Object getElementToOpen(Match match) {
return match.getElement();
}
private IEditorPart showWithoutReuse(Object element, IWorkbenchPage wbPage)
throws PartInitException, ModelException {
return EditorUtility.openInEditor(element, false);
}
private IEditorPart showWithReuse(Object element, IWorkbenchPage wbPage)
throws ModelException, PartInitException {
if (element instanceof IModelElement) {
IModelElement module = ((IModelElement) element)
.getAncestor(IModelElement.SOURCE_MODULE);
if (module instanceof IExternalSourceModule) {
String editorID = getEditorID(module);
return showInEditor(wbPage, new ExternalStorageEditorInput(
(IExternalSourceModule) module), editorID);
} else if (module instanceof SourceModule) {
String editorID = getEditorID(module);
IFile file = getFile(element);
return showInEditor(wbPage, new FileEditorInput(file),
editorID);
}
}
IFile file = getFile(element);
if (file != null) {
String editorID = getEditorID(file);
return showInEditor(wbPage, new FileEditorInput(file), editorID);
}
return null;
}
private IFile getFile(Object element) throws ModelException {
if (element instanceof IFile)
return (IFile) element;
if (element instanceof IModelElement) {
IModelElement jElement = (IModelElement) element;
ISourceModule cu = (ISourceModule) jElement
.getAncestor(IModelElement.SOURCE_MODULE);
if (cu != null) {
return (IFile) cu.getCorrespondingResource();
}
}
return null;
}
private String getEditorID(IFile file) throws PartInitException {
IEditorDescriptor desc = null;
if (desc == null) {
return DLTKUIPlugin.getDefault().getWorkbench().getEditorRegistry()
.findEditor(IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID)
.getId();
}
return desc.getId();
}
private String getEditorID(IModelElement module) throws PartInitException {
IDLTKUILanguageToolkit toolkit = DLTKUILanguageManager
.getLanguageToolkit(module);
String editorId = toolkit.getEditorId(module);
IEditorDescriptor desc = null;
if (editorId != null) {
desc = DLTKUIPlugin.getDefault().getWorkbench().getEditorRegistry()
.findEditor(editorId);
}
if (desc == null) {
return DLTKUIPlugin.getDefault().getWorkbench().getEditorRegistry()
.findEditor(IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID)
.getId();
}
return desc.getId();
}
private boolean isPinned(IEditorPart editor) {
if (editor == null)
return false;
IEditorReference[] editorRefs = editor.getEditorSite().getPage()
.getEditorReferences();
int i = 0;
while (i < editorRefs.length) {
if (editor.equals(editorRefs[i].getEditor(false)))
return editorRefs[i].isPinned();
i++;
}
return false;
}
private IEditorPart showInEditor(IWorkbenchPage page, IEditorInput input,
String editorId) {
IEditorPart editor = page.findEditor(input);
if (editor != null)
page.bringToTop(editor);
else {
IEditorPart reusedEditor = getReusedEditor();
boolean isOpen = false;
if (reusedEditor != null) {
IEditorReference[] parts = page.getEditorReferences();
int i = 0;
while (!isOpen && i < parts.length)
isOpen = reusedEditor == parts[i++].getEditor(false);
}
boolean canBeReused = isOpen && !reusedEditor.isDirty()
&& !isPinned(reusedEditor);
boolean showsSameInputType = reusedEditor != null
&& reusedEditor.getSite().getId().equals(editorId);
if (canBeReused && !showsSameInputType) {
page.closeEditor(reusedEditor, false);
setReusedEditor(null);
}
if (canBeReused && showsSameInputType) {
((IReusableEditor) reusedEditor).setInput(input);
page.bringToTop(reusedEditor);
editor = reusedEditor;
} else {
try {
editor = page.openEditor(input, editorId, false);
if (editor instanceof IReusableEditor)
setReusedEditor(editor);
else
setReusedEditor(null);
} catch (PartInitException ex) {
MessageDialog.openError(
DLTKUIPlugin.getActiveWorkbenchShell(),
SearchMessages.Search_Error_openEditor_title,
SearchMessages.Search_Error_openEditor_message);
return null;
}
}
}
return editor;
}
private IEditorPart getReusedEditor() {
if (fReusedEditorWatcher != null)
return fReusedEditorWatcher.getReusedEditor();
return null;
}
private void setReusedEditor(IEditorPart editor) {
if (fReusedEditorWatcher == null) {
fReusedEditorWatcher = new ReusedEditorWatcher();
}
fReusedEditorWatcher.initialize(editor);
}
}