/*
* Copyright (c) 2012, the Dart project authors.
*
* Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.dart.tools.ui;
import com.google.common.base.Charsets;
import com.google.dart.engine.context.AnalysisContext;
import com.google.dart.engine.element.Element;
import com.google.dart.engine.source.Source;
import com.google.dart.tools.core.DartCore;
import com.google.dart.tools.core.analysis.model.IFileInfo;
import com.google.dart.tools.core.analysis.model.ProjectManager;
import com.google.dart.tools.core.analysis.model.ResourceMap;
import com.google.dart.tools.core.internal.util.ResourceUtil;
import com.google.dart.tools.core.model.DartModelException;
import com.google.dart.tools.core.model.SourceReference;
import com.google.dart.tools.internal.corext.refactoring.util.DartElementUtil;
import com.google.dart.tools.ui.internal.SharedImages;
import com.google.dart.tools.ui.internal.text.editor.DartEditor;
import com.google.dart.tools.ui.internal.text.editor.EditorUtility;
import com.google.dart.tools.ui.text.IColorManager;
import org.dartlang.analysis.server.protocol.Location;
import org.dartlang.analysis.server.protocol.NavigationTarget;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;
import org.eclipse.ui.texteditor.AbstractTextEditor;
import org.eclipse.ui.texteditor.IDocumentProvider;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.Reader;
/**
* Central access point for the Dart UI plug-in (id <code>"com.google.dart.tools.ui"</code>). This
* class provides static methods for:
* <ul>
* <li>creating various kinds of selection dialogs to present a collection of Dart elements to the
* user and let them make a selection.</li>
* <li>opening a Dart editor on a compilation unit.</li>
* </ul>
* <p>
* This class provides static methods and fields only; it is not intended to be instantiated or
* subclassed by clients.
*/
public final class DartUI {
private static ISharedImages fgSharedImages = null;
/**
* The id of the Dart UI plug-in (value <code>"com.google.dart.tools.ui"</code>).
*/
public static final String ID_PLUGIN = "com.google.dart.tools.ui"; //$NON-NLS-1$
/**
* The id of the Dart perspective (value <code>"com.google.dart.tools.ui.JavaPerspective"</code>).
*/
public static final String ID_PERSPECTIVE = "com.google.dart.tools.ui.JavaPerspective"; //$NON-NLS-1$
/**
* The id of the JavaScript action set (value
* <code>"com.google.dart.tools.ui.JavaActionSet"</code>).
*/
public static final String ID_ACTION_SET = "com.google.dart.tools.ui.JavaActionSet"; //$NON-NLS-1$
/**
* The id of the JavaScript Element Creation action set (value
* <code>"com.google.dart.tools.ui.JavaElementCreationActionSet"</code>).
*/
public static final String ID_ELEMENT_CREATION_ACTION_SET = "com.google.dart.tools.ui.JavaElementCreationActionSet"; //$NON-NLS-1$
/**
* The id of the JavaScript Coding action set (value
* <code>"com.google.dart.tools.ui.CodingActionSet"</code>).
*/
public static final String ID_CODING_ACTION_SET = "com.google.dart.tools.ui.CodingActionSet"; //$NON-NLS-1$
/**
* The id of the JavaScript action set for open actions (value
* <code>"com.google.dart.tools.ui.A_OpenActionSet"</code>).
*/
public static final String ID_OPEN_ACTION_SET = "com.google.dart.tools.ui.A_OpenActionSet"; //$NON-NLS-1$
/**
* The id of the JavaScript Search action set (value
* <code>com.google.dart.tools.ui.SearchActionSet"</code>).
*/
public static final String ID_SEARCH_ACTION_SET = "com.google.dart.tools.ui.SearchActionSet"; //$NON-NLS-1$
/**
* The editor part id of the editor that presents JavaScript compilation units (value
* <code>"com.google.dart.tools.ui.text.editor.CompilationUnitEditor"</code> ).
*/
public static final String ID_CU_EDITOR = "com.google.dart.tools.ui.text.editor.CompilationUnitEditor"; //$NON-NLS-1$
/**
* The editor part id of the editor that presents JavaScript binary class files (value
* <code>"com.google.dart.tools.ui.ClassFileEditor"</code>).
*/
public static final String ID_CF_EDITOR = "com.google.dart.tools.ui.ClassFileEditor"; //$NON-NLS-1$
/**
* The editor part id of the default text editor (used in the RCP but not the plugin).
*/
public static final String ID_DEFAULT_TEXT_EDITOR = "com.google.dart.tools.ui.text.editor.TextEditor";
/**
* The editor part id of the code snippet editor (value
* <code>"com.google.dart.tools.ui.SnippetEditor"</code>).
*/
public static final String ID_SNIPPET_EDITOR = "com.google.dart.tools.ui.SnippetEditor"; //$NON-NLS-1$
/**
* The view part id of the Problems view (value
* <code>"com.google.dart.tools.ui.ProblemsView"</code>).
*/
public static final String ID_PROBLEMS = "com.google.dart.tools.ui.ProblemsView"; //$NON-NLS-1$
/**
* The view part id of the type hierarchy part (value
* <code>"com.google.dart.tools.ui.TypeHierarchy"</code>).
* <p>
* When this id is used to access a view part with <code>IWorkbenchPage.findView</code> or
* <code>showView</code>, the returned <code>IViewPart</code> can be safely cast to an
* <code>ITypeHierarchyViewPart</code>.
* </p>
*
* @see ITypeHierarchyViewPart
* @see org.eclipse.ui.IWorkbenchPage#findView(java.lang.String)
* @see org.eclipse.ui.IWorkbenchPage#showView(java.lang.String)
*/
public static final String ID_TYPE_HIERARCHY = "com.google.dart.tools.ui.TypeHierarchy"; //$NON-NLS-1$
/**
* The view part id of the source (declaration) view (value
* <code>"com.google.dart.tools.ui.SourceView"</code>).
*
* @see org.eclipse.ui.IWorkbenchPage#findView(java.lang.String)
* @see org.eclipse.ui.IWorkbenchPage#showView(java.lang.String)
*/
public static final String ID_SOURCE_VIEW = "com.google.dart.tools.ui.SourceView"; //$NON-NLS-1$
/**
* The view part id of the Files view (value <code>"com.google.dart.tools.ui.FileExplorer"</code>
* ).
*/
public static final String ID_FILE_EXPLORER = "com.google.dart.tools.ui.FileExplorer"; //$NON-NLS-1$
/**
* The view part id of the Apps view (value <code>"com.google.dart.tools.ui.AppsView"</code>).
*/
public static final String ID_APPS_VIEW = "com.google.dart.tools.ui.AppsView"; //$NON-NLS-1$
/**
* The view part id of the Console view (value <code>"com.google.dart.tools.ui.console"</code>).
*/
public static final String ID_CONSOLE_VIEW = "com.google.dart.tools.ui.console"; //$NON-NLS-1$
public static final String ID_INSPECTOR_VIEW = "com.google.dart.tools.debug.objectInspectorView"; //$NON-NLS-1$
/**
* The view part id of the Files view (value <code>"com.google.dart.tools.ui.FilesView"</code> ).
*/
public static final String ID_FILE_VIEW = "com.google.dart.tools.ui.FilesView"; //$NON-NLS-1$
/**
* The view part id of the Tests view (<code>"com.google.dart.tools.ui.DartUnitView"</code>).
*/
public static final String ID_DARTUNIT_VIEW = "com.google.dart.tools.ui.DartUnitView"; //$NON-NLS-1$
/**
* The view part id of the JavaScript Documentation view (value
* <code>"com.google.dart.tools.ui.JavadocView"</code>).
*
* @see org.eclipse.ui.IWorkbenchPage#findView(java.lang.String)
* @see org.eclipse.ui.IWorkbenchPage#showView(java.lang.String)
*/
public static final String ID_JAVADOC_VIEW = "com.google.dart.tools.ui.JavadocView"; //$NON-NLS-1$
/**
* The id of the JavaScript Browsing Perspective (value
* <code>"com.google.dart.tools.ui.JavaBrowsingPerspective"</code>).
*/
public static String ID_BROWSING_PERSPECTIVE = "com.google.dart.tools.ui.JavaBrowsingPerspective"; //$NON-NLS-1$
/**
* The view part id of the JavaScript Browsing Projects view (value
* <code>"com.google.dart.tools.ui.ProjectsView"</code>).
*/
public static String ID_PROJECTS_VIEW = "com.google.dart.tools.ui.ProjectsView"; //$NON-NLS-1$
/**
* The view part id of the JavaScript Browsing Packages view (value
* <code>"com.google.dart.tools.ui.PackagesView"</code>).
*/
public static String ID_PACKAGES_VIEW = "com.google.dart.tools.ui.PackagesView"; //$NON-NLS-1$
/**
* The view part id of the JavaScript Browsing Types view (value
* <code>"com.google.dart.tools.ui.TypesView"</code>).
*/
public static String ID_TYPES_VIEW = "com.google.dart.tools.ui.TypesView"; //$NON-NLS-1$
/**
* The view part id of the JavaScript Browsing Members view (value
* <code>"com.google.dart.tools.ui.MembersView"</code>).
*/
public static String ID_MEMBERS_VIEW = "com.google.dart.tools.ui.MembersView"; //$NON-NLS-1$
/**
* The maximal length of a document for which we want to support Dart editing features.
*/
private static final int MAX_DOCUMENT_LENGTH = (int) (1.5 * 1024 * 1024);
/**
* The maximal length of a line in a document for which we want to support Dart editing features.
*/
private static final int MAX_LINE_LENGTH = 1000;
/**
* Returns the color manager the Dart UI plug-in which is used to manage any Dart-specific colors
* needed for such things like syntax highlighting.
*
* @return the color manager to be used for Dart text viewers
*/
public static IColorManager getColorManager() {
return DartToolsPlugin.getDefault().getDartTextTools().getColorManager();
}
/**
* Returns the transfer instance used to copy/paste Dart elements to and from the clipboard.
* Objects managed by this transfer instance are of type <code>DartElement[]</code>. So to access
* data from the clipboard clients should use the following code snippet:
*
* <pre>
* DartElement[] elements = (DartElement[]) clipboard.getContents(DartUI.getDartElementClipboardTransfer());
* </pre>
*
* To put elements into the clipboard use the following snippet:
*
* <pre>
* DartElement[] dartElements= ...;
* clipboard.setContents(
* new Object[] { dartElements },
* new Transfer[] { DartUI.getDartElementClipboardTransfer() } );
* </pre>
*
* @return returns the transfer object used to copy/paste Dart elements to and from the clipboard
*/
public static Transfer getDartElementClipboardTransfer() {
// TODO (pquitslund): implement cliboard transfer
// return JavaElementTransfer.getInstance();
return null;
}
/**
* Returns the DocumentProvider used for Dart compilation units.
*
* @return the DocumentProvider for Dart compilation units.
* @see IDocumentProvider
*/
public static IDocumentProvider getDocumentProvider() {
return DartToolsPlugin.getDefault().getCompilationUnitDocumentProvider();
}
public static Color getEditorBackground(IPreferenceStore prefs, Display display) {
return prefs.getBoolean(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT) ? null
: createColor(prefs, AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND, display);
}
public static Color getEditorForeground(IPreferenceStore prefs, Display display) {
return prefs.getBoolean(AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT) ? null
: createColor(prefs, AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND, display);
}
/**
* Returns the Dart element wrapped by the given editor input.
*
* @param editorInput the editor input
* @return the Dart element wrapped by <code>editorInput</code> or <code>null</code> if none
*/
public static Element getEditorInputDartElement2(IEditorInput editorInput) {
//TODO (pquitslund): add support for external compilation units
// if (editorInput instanceof ExternalCompilationUnitEditorInput) {
// return ((ExternalCompilationUnitEditorInput) editorInput).getCompilationUnit();
// }
//TODO (pquitslund): consider doing this without going through the adapter service
return (Element) editorInput.getAdapter(Element.class);
}
public static Color getEditorSelectionBackground(IPreferenceStore prefs, Display display) {
return prefs.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_BACKGROUND_DEFAULT_COLOR)
? null : createColor(
prefs,
AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_BACKGROUND_COLOR,
display);
}
public static Color getEditorSelectionForeground(IPreferenceStore prefs, Display display) {
return prefs.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_FOREGROUND_DEFAULT_COLOR)
? null : createColor(
prefs,
AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_FOREGROUND_COLOR,
display);
}
/**
* @return the {@link IFile} with {@link #element} to open, may be {@code null}.
*/
public static IFile getElementFile(Element element) {
ResourceMap map = getResourceMap(element);
Source source = element.getSource();
return getSourceFile(map, source);
}
/**
* Returns the shared images for the Dart UI.
*
* @return the shared images manager
*/
public static ISharedImages getSharedImages() {
if (fgSharedImages == null) {
fgSharedImages = new SharedImages();
}
return fgSharedImages;
}
/**
* @return the {@link IFile} to open for ""path, may be {@code null}.
*/
public static IFile getSourceFile(String source) {
File javaFile = new File(source);
return ResourceUtil.getFile(javaFile);
}
public static Color getViewerBackground(IPreferenceStore prefs, Display display) {
// TODO(messick) Use a color identifier distinct from the editor.
return prefs.getBoolean(AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND_SYSTEM_DEFAULT) ? null
: createColor(prefs, AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND, display);
}
public static Color getViewerForeground(IPreferenceStore prefs, Display display) {
// TODO(messick) Use a color identifier distinct from the editor.
return prefs.getBoolean(AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT) ? null
: createColor(prefs, AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND, display);
}
public static Color getViewerSelectionBackground(IPreferenceStore prefs, Display display) {
// TODO(messick) Use a color identifier distinct from the editor.
return prefs.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_BACKGROUND_DEFAULT_COLOR)
? null : createColor(
prefs,
AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_BACKGROUND_COLOR,
display);
}
public static Color getViewerSelectionForeground(IPreferenceStore prefs, Display display) {
// TODO(messick) Use a color identifier distinct from the editor.
return prefs.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_FOREGROUND_DEFAULT_COLOR)
? null : createColor(
prefs,
AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SELECTION_FOREGROUND_COLOR,
display);
}
//TODO (pquitslund): implement when we have dart doc
// /**
// * Returns the Javadoc base URL for an element. The base location contains the
// * index file. This location doesn't have to exist. Returns <code>null</code>
// * if no javadoc location has been attached to the element's library or
// * project. Example of a returned URL is
// * <i>http://www.junit.org/junit/javadoc</i>.
// *
// * @param element the element for which the documentation URL is requested.
// * @return the base location
// * @throws DartModelException thrown when the element can not be accessed
// */
// public static URL getJSdocBaseLocation(DartElement element)
// throws DartModelException {
// return JavaDocLocations.getJavadocBaseLocation(element);
// }
//
// /**
// * Returns the Javadoc URL for an element. Example of a returned URL is
// * <i>http://www.junit.org/junit/javadoc/junit/extensions/TestSetup.html</i>.
// * This returned location doesn't have to exist. Returns <code>null</code> if
// * no javadoc location has been attached to the element's library or project.
// *
// * @param element the element for which the documentation URL is requested.
// * @param includeAnchor If set, the URL contains an anchor for member
// * references:
// * <i>http://www.junit.org/junit/javadoc/junit/extensions/
// * TestSetup.html#run(junit.framework.TestResult)</i>. Note that this
// * involves type resolving and is a more expensive call than without
// * anchor.
// * @return the Javadoc URL for the element
// * @throws DartModelException thrown when the element can not be accessed
// */
// public static URL getJSdocLocation(DartElement element, boolean includeAnchor)
// throws DartModelException {
// return JavaDocLocations.getJavadocLocation(element, includeAnchor);
// }
//
// /**
// * Returns the Javadoc location for library's classpath entry or
// * <code>null</code> if no location is available. Note that only classpath
// * entries of kind {@link IIncludePathEntry#CPE_LIBRARY} and
// * {@link IIncludePathEntry#CPE_VARIABLE} support Javadoc locations.
// *
// * @param entry the classpath entry to get the Javadoc location for
// * @return the Javadoc location or<code>null</code> if no Javadoc location is
// * available
// * @throws IllegalArgumentException Thrown when the entry is <code>null</code>
// * or not of kind {@link IIncludePathEntry#CPE_LIBRARY} or
// * {@link IIncludePathEntry#CPE_VARIABLE}.
// */
// public static URL getLibraryJSdocLocation(IIncludePathEntry entry) {
// return JavaDocLocations.getLibraryJavadocLocation(entry);
// }
//
// /**
// * Returns the Javadoc location for a JavaScript project or <code>null</code>
// * if no location is available. This location is used for all types located in
// * the project's source folders.
// *
// * @param project the project
// * @return the Javadoc location for a JavaScript project or <code>null</code>
// */
// public static URL getProjectJSdocLocation(DartProject project) {
// return JavaDocLocations.getProjectJavadocLocation(project);
// }
//
// /**
// * Sets the Javadoc location for a JavaScript project. This location is used
// * for all types located in the project's source folders.
// *
// * @param project the project
// * @param url the Javadoc location to set. This location should contain
// * index.html and a file 'package-list'. <code>null</code> clears the
// * current documentation location.
// */
// public static void setProjectJSdocLocation(DartProject project, URL url) {
// JavaDocLocations.setProjectJavadocLocation(project, url);
// }
/**
* Eclipse StyledText becomes very slow (practically hangs) when it attempts to render a long line
* with many style ranges. We need to check for this and avoid creating styles.
* <p>
* https://code.google.com/p/dart/issues/detail?id=17204
* <p>
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=196731
*/
public static boolean isTooComplexDartDocument(IDocument document) {
if (document == null) {
return false;
}
if (document.getLength() > MAX_DOCUMENT_LENGTH) {
return true;
}
int numberOfLines = document.getNumberOfLines();
for (int i = 0; i < numberOfLines; i++) {
try {
if (document.getLineLength(i) > MAX_LINE_LENGTH) {
return true;
}
} catch (BadLocationException e) {
}
}
return false;
}
/**
* Checks if the given Dart file will be too complex for the opening it in the Dart editor.
*/
public static boolean isTooComplexDartFile(IFile resource) {
IPath resourceLoc = resource.getLocation();
if (resourceLoc == null) {
return false;
}
// should not be too long
File file = resourceLoc.toFile();
if (file.length() > MAX_DOCUMENT_LENGTH) {
return true;
}
// check line length
try {
Reader reader = new InputStreamReader(new FileInputStream(file), Charsets.UTF_8);
BufferedReader br = new BufferedReader(reader);
try {
String line = br.readLine();
if (line == null) {
return false;
}
if (line.length() > MAX_LINE_LENGTH) {
return true;
}
} finally {
br.close();
}
} catch (Throwable e) {
return true;
}
// OK
return false;
}
public static IEditorPart openFilePath(String path, boolean activate) throws PartInitException,
DartModelException {
File javaFile = new File(path);
IFile file = ResourceUtil.getFile(javaFile);
if (file != null) {
return openFile(file, activate);
}
// fallback for SDK, which sources are is not a IFile(s)
return EditorUtility.openInEditor(javaFile, activate);
}
/**
* Opens an editor at the given position in the active page.
*/
public static IEditorPart openFilePath(String filePath, boolean activate, int offset, int length)
throws Exception {
IEditorPart editor = openFilePath(filePath, activate);
EditorUtility.revealInEditor(editor, offset, length);
return editor;
}
/**
* Opens an editor with {@link Element} in context of the given {@link DartEditor}.
*
* @param contextEditor the {@link DartEditor} to use as context, may be {@code null}.
* @param element the {@link Element} to open in reveal.
* @return the opened editor or {@code null} if by some reason editor was not opened.
*/
public static IEditorPart openInEditor(DartEditor contextEditor, Element element, boolean activate)
throws Exception {
IFile contextFile = contextEditor != null ? contextEditor.getInputResourceFile() : null;
return openInEditor(contextFile, element, activate);
}
/**
* Opens an editor on the given Dart element in the active page. Valid elements are all Dart
* elements that are {@link SourceReference}. For elements inside a compilation unit, the parent
* is opened in the editor is opened and the element revealed. If there already is an open Dart
* editor for the given element, it is returned.
*
* @param element the input element; either a compilation unit ( <code>CompilationUnit</code>) or
* a class file ( <code>IClassFile</code>) or source references inside.
* @return returns the editor part of the opened editor or <code>null</code> if the element is not
* a {@link SourceReference} or the file was opened in an external editor.
* @exception PartInitException if the editor could not be initialized or no workbench page is
* active
* @exception DartModelException if this element does not exist or if an exception occurs while
* accessing its underlying resource
*/
public static IEditorPart openInEditor(Element element) throws DartModelException,
PartInitException {
element = DartElementUtil.getVariableIfSyntheticAccessor(element);
element = DartElementUtil.getAccessorIfSyntheticVariable(element);
element = DartElementUtil.getExplicitIfSyntheticImplicitConstructor(element);
element = DartElementUtil.getClassIfSyntheticDefaultConstructor(element);
return openInEditor(element, true, true);
}
/**
* Opens an editor on the given Dart element in the active page. Valid elements are all Dart
* elements that are {@link SourceReference}. For elements inside a compilation unit, the parent
* is opened in the editor is opened. If there already is an open Dart editor for the given
* element, it is returned.
*
* @param element the input element; either a compilation unit ( <code>CompilationUnit</code>) or
* a class file ( <code>IClassFile</code>) or source references inside.
* @param activate if set, the editor will be activated.
* @param reveal if set, the element will be revealed.
* @return returns the editor part of the opened editor or <code>null</code> if the element is not
* a {@link SourceReference} or the file was opened in an external editor.
* @exception PartInitException if the editor could not be initialized or no workbench page is
* active
* @exception DartModelException if this element does not exist or if an exception occurs while
* accessing its underlying resource
*/
public static IEditorPart openInEditor(Element element, boolean activate, boolean reveal)
throws DartModelException, PartInitException {
if (element == null) {
return null;
}
ResourceMap map = getResourceMap(element);
Source source = element.getSource();
IEditorPart editor = openSource(map, source, activate);
if (reveal) {
EditorUtility.revealInEditor(editor, element);
}
return editor;
}
/**
* Opens an editor with {@link Element} in context of the given {@link IFile}.
*
* @param context the {@link IResource} to open {@link Element} in, may be {@code null}.
* @param element the {@link Element} to open in reveal.
* @return the opened editor or {@code null} if by some reason editor was not opened.
*/
public static IEditorPart openInEditor(IResource context, Element element, boolean activate)
throws Exception {
if (element == null) {
return null;
}
IFile file = getElementFile(element);
String name = element.getDisplayName();
int nameOffset = element.getNameOffset();
int nameLength = name != null ? name.length() : 0;
return openFile(file, activate, nameOffset, nameLength);
}
/**
* Opens an editor at the given position in the active page.
*/
public static IEditorPart openInEditor(IResource context, Source source, boolean activate,
int offset, int length) throws Exception {
ResourceMap map = getResourceMap(context);
return openSource(map, source, activate, offset, length);
}
/**
* Opens an editor with {@link com.google.dart.server.Element}.
*
* @param target the {@link NavigationTarget} to open in reveal
* @return the opened editor or {@code null} if by some reason editor was not opened
*/
public static IEditorPart openInEditor(org.dartlang.analysis.server.protocol.Element target,
boolean activate) throws Exception {
if (target == null) {
return null;
}
Location location = target.getLocation();
if (location == null) {
return null;
}
String path = location.getFile();
IEditorPart editor = openFilePath(path, activate);
if (editor != null) {
int offset = location.getOffset();
int length = location.getLength();
EditorUtility.revealInEditor(editor, offset, length);
}
return editor;
}
/**
* Opens an editor with {@link NavigationTarget}.
*
* @param target the {@link NavigationTarget} to open in reveal
* @return the opened editor or {@code null} if by some reason editor was not opened
*/
public static IEditorPart openInEditor(
org.dartlang.analysis.server.protocol.NavigationTarget target, boolean activate)
throws Exception {
if (target == null) {
return null;
}
String path = target.getFile();
IEditorPart editor = openFilePath(path, activate);
if (editor != null) {
int offset = target.getOffset();
int length = target.getLength();
EditorUtility.revealInEditor(editor, offset, length);
}
return editor;
}
/**
* A shared method to show the warning about "too complex" Dart file.
*/
public static void showTooComplexDartFileWarning(IEditorPart editor) {
if (editor != null) {
editor.getEditorSite().getActionBars().getStatusLineManager().setErrorMessage(
"This file is too complex to open it in the Dart editor.");
}
}
private static Color createColor(IPreferenceStore store, String key, Display display) {
// TODO(messick) Remove display or use it instead of color manager
RGB rgb = null;
if (store.contains(key)) {
if (store.isDefault(key)) {
rgb = PreferenceConverter.getDefaultColor(store, key);
} else {
rgb = PreferenceConverter.getColor(store, key);
}
if (rgb != null) {
return getColorManager().getColor(rgb);
}
}
return null;
}
private static ResourceMap getResourceMap(Element element) {
if (element == null) {
return null;
}
AnalysisContext context = element.getContext();
return DartCore.getProjectManager().getResourceMap(context);
}
private static ResourceMap getResourceMap(IResource context) {
if (context == null) {
return null;
}
return DartCore.getProjectManager().getResourceMap(context);
}
/**
* @return the {@link IFile} to open for the {@link Source}, may be {@code null}.
*/
private static IFile getSourceFile(ResourceMap map, Source source) {
ProjectManager projectManager = DartCore.getProjectManager();
// validate Source
if (source == null) {
return null;
}
// fallback
if (map == null) {
return (IFile) projectManager.getResource(source);
}
// use ResourceMap
IFile file = map.getResource(source);
// self-reference tweak
if (file != null) {
IResource resource = projectManager.getResource(source);
if (resource instanceof IFile) {
// on Windows, check if there is an resource in project/lib in workspace that is
// the same as the one in packages. If so, open the local source and not packages
if (DartCore.isWindows()
&& resource.getFullPath().toString().contains(DartCore.PACKAGES_DIRECTORY_PATH)) {
String path = resource.getFullPath().toString();
int index = path.indexOf(DartCore.PACKAGES_DIRECTORY_PATH);
String packageUri = DartCore.PACKAGE_SCHEME_SPEC
+ path.substring(index + DartCore.PACKAGES_DIRECTORY_PATH.length());
IFileInfo info = DartCore.getProjectManager().resolveUriToFileInfo(
map.getResource(),
packageUri);
if (info != null && info.getResource() != null) {
return info.getResource();
}
}
file = (IFile) resource;
}
}
return file;
}
private static IEditorPart openFile(IFile file, boolean activate) throws PartInitException,
DartModelException {
if (file == null) {
return null;
}
return EditorUtility.openInEditor(file, activate);
}
private static IEditorPart openFile(IFile file, boolean activate, int offset, int length)
throws Exception {
IEditorPart editor = openFile(file, activate);
if (editor != null) {
EditorUtility.revealInEditor(editor, offset, length);
}
return editor;
}
private static IEditorPart openSource(ResourceMap map, Source source, boolean activate)
throws PartInitException, DartModelException {
IFile file = getSourceFile(map, source);
if (file != null) {
return openFile(file, activate);
}
// fallback for SDK, which sources are is not a IFile(s)
return EditorUtility.openInEditor(source, activate);
}
private static IEditorPart openSource(ResourceMap map, Source source, boolean activate,
int offset, int length) throws Exception {
IEditorPart editor = openSource(map, source, activate);
if (editor != null) {
EditorUtility.revealInEditor(editor, offset, length);
}
return editor;
}
private DartUI() {
// prevent instantiation of DartUI.
}
}