1 /*******************************************************************************
2  * Copyright (c) 2000, 2008 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.search.internal.ui.text;
15 
16 import java.util.HashMap;
17 
18 import org.eclipse.core.runtime.CoreException;
19 
20 import org.eclipse.core.resources.IFile;
21 import org.eclipse.core.resources.IMarker;
22 
23 import org.eclipse.ui.IEditorDescriptor;
24 import org.eclipse.ui.IEditorInput;
25 import org.eclipse.ui.IEditorPart;
26 import org.eclipse.ui.IEditorReference;
27 import org.eclipse.ui.IEditorRegistry;
28 import org.eclipse.ui.IReusableEditor;
29 import org.eclipse.ui.IWorkbenchPage;
30 import org.eclipse.ui.PartInitException;
31 import org.eclipse.ui.PlatformUI;
32 import org.eclipse.ui.ide.IDE;
33 import org.eclipse.ui.part.FileEditorInput;
34 
35 import org.eclipse.ui.texteditor.ITextEditor;
36 
37 import org.eclipse.search.internal.ui.SearchMessages;
38 import org.eclipse.search.ui.NewSearchUI;
39 
40 public class EditorOpener {
41 
42 	private IEditorReference fReusedEditor;
43 
open(IWorkbenchPage wbPage, IFile file, boolean activate)44 	public IEditorPart open(IWorkbenchPage wbPage, IFile file, boolean activate) throws PartInitException {
45 		if (NewSearchUI.reuseEditor())
46 			return showWithReuse(file, wbPage, getEditorID(file), activate);
47 		return showWithoutReuse(file, wbPage, getEditorID(file), activate);
48 	}
49 
openAndSelect(IWorkbenchPage wbPage, IFile file, int offset, int length, boolean activate)50 	public IEditorPart openAndSelect(IWorkbenchPage wbPage, IFile file, int offset, int length, boolean activate) throws PartInitException {
51 		String editorId= null;
52 		IEditorDescriptor desc = IDE.getEditorDescriptor(file, true, true);
53 		if (desc == null || !desc.isInternal()) {
54 			editorId= "org.eclipse.ui.DefaultTextEditor"; //$NON-NLS-1$
55 		} else {
56 			editorId= desc.getId();
57 		}
58 
59 		IEditorPart editor;
60 		if (NewSearchUI.reuseEditor()) {
61 			editor= showWithReuse(file, wbPage, editorId, activate);
62 		} else {
63 			editor= showWithoutReuse(file, wbPage, editorId, activate);
64 		}
65 
66 		if (editor instanceof ITextEditor) {
67 			ITextEditor textEditor= (ITextEditor) editor;
68 			textEditor.selectAndReveal(offset, length);
69 		} else if (editor != null) {
70 			showWithMarker(editor, file, offset, length);
71 		}
72 		return editor;
73 	}
74 
showWithoutReuse(IFile file, IWorkbenchPage wbPage, String editorID, boolean activate)75 	private IEditorPart showWithoutReuse(IFile file, IWorkbenchPage wbPage, String editorID, boolean activate) throws PartInitException {
76 		return IDE.openEditor(wbPage, file, editorID, activate);
77 	}
78 
79 
getEditorID(IFile file)80 	private String getEditorID(IFile file) throws PartInitException {
81 		IEditorDescriptor desc = IDE.getEditorDescriptor(file, true, true);
82 		if (desc == null)
83 			return PlatformUI.getWorkbench().getEditorRegistry().findEditor(IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID)
84 					.getId();
85 		return desc.getId();
86 	}
87 
showWithReuse(IFile file, IWorkbenchPage page, String editorId, boolean activate)88 	private IEditorPart showWithReuse(IFile file, IWorkbenchPage page, String editorId, boolean activate) throws PartInitException {
89 		IEditorInput input= new FileEditorInput(file);
90 		IEditorPart editor= page.findEditor(input);
91 		if (editor != null) {
92 			page.bringToTop(editor);
93 			if (activate) {
94 				page.activate(editor);
95 			}
96 			return editor;
97 		}
98 		IEditorReference reusedEditorRef= fReusedEditor;
99 		if (reusedEditorRef !=  null) {
100 			boolean isOpen= reusedEditorRef.getEditor(false) != null;
101 			boolean canBeReused= isOpen && !reusedEditorRef.isDirty() && !reusedEditorRef.isPinned();
102 			if (canBeReused) {
103 				boolean showsSameInputType= reusedEditorRef.getId().equals(editorId);
104 				if (!showsSameInputType) {
105 					page.closeEditors(new IEditorReference[] { reusedEditorRef }, false);
106 					fReusedEditor= null;
107 				} else {
108 					editor= reusedEditorRef.getEditor(true);
109 					if (editor instanceof IReusableEditor) {
110 						((IReusableEditor) editor).setInput(input);
111 						page.bringToTop(editor);
112 						if (activate) {
113 							page.activate(editor);
114 						}
115 						return editor;
116 					}
117 				}
118 			}
119 		}
120 		editor= page.openEditor(input, editorId, activate);
121 		if (editor instanceof IReusableEditor) {
122 			IEditorReference reference= (IEditorReference) page.getReference(editor);
123 			fReusedEditor= reference;
124 		} else {
125 			fReusedEditor= null;
126 		}
127 		return editor;
128 	}
129 
showWithMarker(IEditorPart editor, IFile file, int offset, int length)130 	private void showWithMarker(IEditorPart editor, IFile file, int offset, int length) throws PartInitException {
131 		IMarker marker= null;
132 		try {
133 			marker= file.createMarker(NewSearchUI.SEARCH_MARKER);
134 			HashMap<String, Integer> attributes= new HashMap<>(4);
135 			attributes.put(IMarker.CHAR_START, Integer.valueOf(offset));
136 			attributes.put(IMarker.CHAR_END, Integer.valueOf(offset + length));
137 			marker.setAttributes(attributes);
138 			IDE.gotoMarker(editor, marker);
139 		} catch (CoreException e) {
140 			throw new PartInitException(SearchMessages.FileSearchPage_error_marker, e);
141 		} finally {
142 			if (marker != null)
143 				try {
144 					marker.delete();
145 				} catch (CoreException e) {
146 					// ignore
147 				}
148 		}
149 	}
150 
151 }
152