Index: editor/tools/plugins/com.google.dart.tools.ui/src/com/google/dart/tools/ui/internal/text/editor/DartOutlinePage_NEW.java |
diff --git a/editor/tools/plugins/com.google.dart.tools.ui/src/com/google/dart/tools/ui/internal/text/editor/DartOutlinePage.java b/editor/tools/plugins/com.google.dart.tools.ui/src/com/google/dart/tools/ui/internal/text/editor/DartOutlinePage_NEW.java |
similarity index 61% |
copy from editor/tools/plugins/com.google.dart.tools.ui/src/com/google/dart/tools/ui/internal/text/editor/DartOutlinePage.java |
copy to editor/tools/plugins/com.google.dart.tools.ui/src/com/google/dart/tools/ui/internal/text/editor/DartOutlinePage_NEW.java |
index d36f90565a95889494892522e574f78f04cc013c..eea3ff1d055b14fe2b05d42224ae6aa206d41345 100644 |
--- a/editor/tools/plugins/com.google.dart.tools.ui/src/com/google/dart/tools/ui/internal/text/editor/DartOutlinePage.java |
+++ b/editor/tools/plugins/com.google.dart.tools.ui/src/com/google/dart/tools/ui/internal/text/editor/DartOutlinePage_NEW.java |
@@ -1,5 +1,5 @@ |
/* |
- * Copyright (c) 2013, the Dart project authors. |
+ * Copyright (c) 2014, 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 |
@@ -14,9 +14,11 @@ |
package com.google.dart.tools.ui.internal.text.editor; |
import com.google.common.base.Objects; |
-import com.google.dart.engine.ast.CompilationUnit; |
+import com.google.dart.server.Outline; |
+import com.google.dart.server.OutlineKind; |
import com.google.dart.tools.core.DartCore; |
import com.google.dart.tools.internal.search.ui.DartSearchActionGroup; |
+import com.google.dart.tools.ui.DartElementImageDescriptor; |
import com.google.dart.tools.ui.DartPluginImages; |
import com.google.dart.tools.ui.DartToolsPlugin; |
import com.google.dart.tools.ui.actions.InstrumentedAction; |
@@ -26,32 +28,40 @@ import com.google.dart.tools.ui.instrumentation.UIInstrumentationBuilder; |
import com.google.dart.tools.ui.internal.text.DartHelpContextIds; |
import com.google.dart.tools.ui.internal.util.SWTUtil; |
import com.google.dart.tools.ui.internal.viewsupport.ColoredViewersManager; |
+import com.google.dart.tools.ui.internal.viewsupport.ImageDescriptorRegistry; |
+import org.apache.commons.lang3.StringUtils; |
import org.eclipse.core.runtime.Assert; |
-import org.eclipse.core.runtime.IProgressMonitor; |
-import org.eclipse.core.runtime.IStatus; |
import org.eclipse.core.runtime.ListenerList; |
-import org.eclipse.core.runtime.Status; |
import org.eclipse.jface.action.IAction; |
import org.eclipse.jface.action.IMenuListener; |
import org.eclipse.jface.action.IMenuManager; |
import org.eclipse.jface.action.IToolBarManager; |
import org.eclipse.jface.action.MenuManager; |
import org.eclipse.jface.preference.IPreferenceStore; |
+import org.eclipse.jface.resource.ImageDescriptor; |
import org.eclipse.jface.util.IPropertyChangeListener; |
import org.eclipse.jface.util.PropertyChangeEvent; |
+import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider; |
+import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider; |
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.ITreeContentProvider; |
+import org.eclipse.jface.viewers.LabelProvider; |
import org.eclipse.jface.viewers.SelectionChangedEvent; |
import org.eclipse.jface.viewers.StructuredSelection; |
+import org.eclipse.jface.viewers.StyledString; |
import org.eclipse.jface.viewers.TreeViewer; |
import org.eclipse.jface.viewers.Viewer; |
+import org.eclipse.jface.viewers.ViewerComparator; |
import org.eclipse.jface.viewers.ViewerFilter; |
import org.eclipse.swt.SWT; |
import org.eclipse.swt.custom.BusyIndicator; |
+import org.eclipse.swt.graphics.Image; |
+import org.eclipse.swt.graphics.Point; |
import org.eclipse.swt.widgets.Composite; |
import org.eclipse.swt.widgets.Control; |
import org.eclipse.swt.widgets.Display; |
@@ -64,13 +74,76 @@ import org.eclipse.ui.actions.ActionContext; |
import org.eclipse.ui.actions.ActionGroup; |
import org.eclipse.ui.part.IPageSite; |
import org.eclipse.ui.part.Page; |
-import org.eclipse.ui.progress.UIJob; |
import org.eclipse.ui.views.contentoutline.IContentOutlinePage; |
/** |
* {@link IContentOutlinePage} for {@link DartEditor}. |
*/ |
-public class DartOutlinePage extends Page implements IContentOutlinePage { |
+public class DartOutlinePage_NEW extends Page implements IContentOutlinePage { |
+ |
+ /** |
+ * {@link ViewerComparator} for {@link Outline} names. |
+ */ |
+ public static class NameComparator extends ViewerComparator { |
+ private static final int NOT_ELEMENT = 2; |
+ private static final int PRIVATE_ELEMENT = 1; |
+ private static final int PUBLIC_ELEMENT = 0; |
+ |
+ @Override |
+ public int category(Object e) { |
+ if (!(e instanceof Outline)) { |
+ return NOT_ELEMENT; |
+ } |
+ Outline outline = (Outline) e; |
+ // TODO(scheglov) |
+// if (outline.isPrivate()) { |
+// return PRIVATE_ELEMENT; |
+// } |
+ return PUBLIC_ELEMENT; |
+ } |
+ |
+ @Override |
+ public int compare(Viewer viewer, Object e1, Object e2) { |
+ // compare categories |
+ int cat1 = category(e1); |
+ int cat2 = category(e2); |
+ if (cat1 != cat2) { |
+ return cat1 - cat2; |
+ } |
+ // check types |
+ if (!(e1 instanceof Outline)) { |
+ return 0; |
+ } |
+ if (!(e2 instanceof Outline)) { |
+ return 0; |
+ } |
+ // compare names |
+ String name1 = ((Outline) e1).getName(); |
+ String name2 = ((Outline) e2).getName(); |
+ if (name1 == null || name2 == null) { |
+ return 0; |
+ } |
+ return name1.compareTo(name2); |
+ } |
+ } |
+ |
+ /** |
+ * {@link ViewerComparator} for {@link Outline} positions. |
+ */ |
+ public static class PositionComparator extends ViewerComparator { |
+ @Override |
+ public int compare(Viewer viewer, Object e1, Object e2) { |
+ if (!(e1 instanceof Outline)) { |
+ return 0; |
+ } |
+ if (!(e2 instanceof Outline)) { |
+ return 0; |
+ } |
+ int offset1 = ((Outline) e1).getOffset(); |
+ int offset2 = ((Outline) e2).getOffset(); |
+ return offset1 - offset2; |
+ } |
+ } |
private class CollapseAllAction extends InstrumentedAction { |
CollapseAllAction() { |
@@ -164,9 +237,9 @@ public class DartOutlinePage extends Page implements IContentOutlinePage { |
@Override |
public void run() { |
if (on) { |
- viewer.setComparator(LightNodeElements.NAME_COMPARATOR); |
+ viewer.setComparator(NAME_COMPARATOR); |
} else { |
- viewer.setComparator(LightNodeElements.POSITION_COMPARATOR); |
+ viewer.setComparator(POSITION_COMPARATOR); |
} |
} |
}); |
@@ -178,17 +251,161 @@ public class DartOutlinePage extends Page implements IContentOutlinePage { |
} |
} |
+ private static class OutlineContentProvider implements ITreeContentProvider { |
+ @Override |
+ public void dispose() { |
+ } |
+ |
+ @Override |
+ public Object[] getChildren(Object parentElement) { |
+ return ((Outline) parentElement).getChildren(); |
+ } |
+ |
+ @Override |
+ public Object[] getElements(Object inputElement) { |
+ return ((Outline) inputElement).getChildren(); |
+ } |
+ |
+ @Override |
+ public Object getParent(Object element) { |
+ return ((Outline) element).getParent(); |
+ } |
+ |
+ @Override |
+ public boolean hasChildren(Object element) { |
+ return getChildren(element).length != 0; |
+ } |
+ |
+ @Override |
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { |
+ } |
+ } |
+ private static class OutlineLabelProvider extends LabelProvider implements IStyledLabelProvider { |
+ private static final Point SIZE = new Point(22, 16); |
+ private static final ImageDescriptorRegistry registry = DartToolsPlugin.getImageDescriptorRegistry(); |
+ private static final String RIGHT_ARROW = " \u2192 "; //$NON-NLS-1$ |
+ |
+ private static ImageDescriptor getBaseImageDescriptor(OutlineKind kind, boolean isPrivate) { |
+ if (kind == OutlineKind.CLASS) { |
+ return isPrivate ? DartPluginImages.DESC_DART_CLASS_PRIVATE |
+ : DartPluginImages.DESC_DART_CLASS_PUBLIC; |
+ } |
+ if (kind == OutlineKind.FUNCTION_TYPE_ALIAS) { |
+ return isPrivate ? DartPluginImages.DESC_DART_FUNCTIONTYPE_PRIVATE |
+ : DartPluginImages.DESC_DART_FUNCTIONTYPE_PUBLIC; |
+ } |
+ if (kind == OutlineKind.FIELD || kind == OutlineKind.TOP_LEVEL_VARIABLE) { |
+ return isPrivate ? DartPluginImages.DESC_DART_FIELD_PRIVATE |
+ : DartPluginImages.DESC_DART_FIELD_PUBLIC; |
+ } |
+ if (kind == OutlineKind.CONSTRUCTOR || kind == OutlineKind.FUNCTION |
+ || kind == OutlineKind.GETTER || kind == OutlineKind.METHOD || kind == OutlineKind.SETTER) { |
+ return isPrivate ? DartPluginImages.DESC_DART_METHOD_PRIVATE |
+ : DartPluginImages.DESC_DART_METHOD_PUBLIC; |
+ } |
+ return null; |
+ } |
+ |
+ private static ImageDescriptor getImageDescriptor(OutlineKind kind, boolean isPrivate) { |
+ ImageDescriptor base = getBaseImageDescriptor(kind, isPrivate); |
+ if (base == null) { |
+ return null; |
+ } |
+ int flags = 0; |
+ if (kind == OutlineKind.CONSTRUCTOR) { |
+ flags |= DartElementImageDescriptor.CONSTRUCTOR; |
+ } |
+ if (kind == OutlineKind.GETTER) { |
+ flags |= DartElementImageDescriptor.GETTER; |
+ } |
+ if (kind == OutlineKind.SETTER) { |
+ flags |= DartElementImageDescriptor.SETTER; |
+ } |
+ // TODO(scheglov) Analysis Server: add flags: abstract, private, static |
+// // ClassDeclaration |
+// if (node instanceof ClassDeclaration) { |
+// ClassDeclaration classDeclaration = (ClassDeclaration) node; |
+// if (classDeclaration.getAbstractKeyword() != null) { |
+// flags |= DartElementImageDescriptor.ABSTRACT; |
+// } |
+// } |
+// // ConstructorDeclaration |
+// if (node instanceof ConstructorDeclaration) { |
+// flags |= DartElementImageDescriptor.CONSTRUCTOR; |
+// } |
+// // MethodDeclaration |
+// if (node instanceof MethodDeclaration) { |
+// MethodDeclaration method = (MethodDeclaration) node; |
+// if (method.isAbstract()) { |
+// flags |= DartElementImageDescriptor.ABSTRACT; |
+// } |
+// if (method.isStatic()) { |
+// flags |= DartElementImageDescriptor.STATIC; |
+// } |
+// if (method.isGetter()) { |
+// flags |= DartElementImageDescriptor.GETTER; |
+// } |
+// if (method.isSetter()) { |
+// flags |= DartElementImageDescriptor.SETTER; |
+// } |
+// } |
+ // done |
+ return new DartElementImageDescriptor(base, flags, SIZE); |
+ } |
+ |
+ @Override |
+ public Image getImage(Object o) { |
+ Outline outline = (Outline) o; |
+ // TODO(scheglov) Analysis Server: add isPrivate() accessor |
+ boolean isPrivate = outline.getName().startsWith("_"); |
+ ImageDescriptor descriptor = getImageDescriptor(outline.getKind(), isPrivate); |
+ if (descriptor != null) { |
+ return registry.get(descriptor); |
+ } |
+ return null; |
+ } |
+ |
+ @Override |
+ public StyledString getStyledText(Object obj) { |
+ Outline outline = (Outline) obj; |
+ StyledString styledString = new StyledString(getText(obj)); |
+ // append parameters |
+ String parameters = outline.getArguments(); |
+ if (parameters != null) { |
+ styledString.append(parameters, StyledString.DECORATIONS_STYLER); |
+ } |
+ // append return type |
+ String returnType = outline.getReturnType(); |
+ if (!StringUtils.isEmpty(returnType)) { |
+ if (outline.getKind() == OutlineKind.FIELD |
+ || outline.getKind() == OutlineKind.TOP_LEVEL_VARIABLE) { |
+ styledString.append(" : " + returnType, StyledString.QUALIFIER_STYLER); |
+ } else { |
+ styledString.append(RIGHT_ARROW + returnType, StyledString.QUALIFIER_STYLER); |
+ } |
+ } |
+ // done |
+ return styledString; |
+ } |
+ |
+ @Override |
+ public String getText(Object element) { |
+ return ((Outline) element).getName(); |
+ } |
+ } |
+ |
private final ListenerList selectionChangedListeners = new ListenerList(ListenerList.IDENTITY); |
private final String contextMenuID; |
private DartEditor editor; |
+ private Outline input; |
private DartOutlineViewer viewer; |
+ |
private boolean ignoreSelectionChangedEvent = false; |
private Menu contextMenu; |
- private CompositeActionGroup actionGroups; |
- |
- private CompilationUnit input; |
+ private CompositeActionGroup actionGroups; |
private IPreferenceStore preferences; |
+ |
private IPropertyChangeListener propertyChangeListener = new IPropertyChangeListener() { |
@Override |
public void propertyChange(PropertyChangeEvent event) { |
@@ -196,18 +413,21 @@ public class DartOutlinePage extends Page implements IContentOutlinePage { |
} |
}; |
+ private static final ViewerComparator NAME_COMPARATOR = new NameComparator(); |
+ private static final ViewerComparator POSITION_COMPARATOR = new PositionComparator(); |
private static final ViewerFilter PUBLIC_FILTER = new ViewerFilter() { |
@Override |
public boolean select(Viewer viewer, Object parentElement, Object o) { |
- if (o instanceof LightNodeElement) { |
- LightNodeElement element = (LightNodeElement) o; |
- return !element.isPrivate(); |
- } |
+ // TODO(scheglov) |
+// if (o instanceof LightNodeElement) { |
+// LightNodeElement element = (LightNodeElement) o; |
+// return !element.isPrivate(); |
+// } |
return false; |
} |
}; |
- public DartOutlinePage(String contextMenuID, DartEditor editor) { |
+ public DartOutlinePage_NEW(String contextMenuID, DartEditor editor) { |
Assert.isNotNull(editor); |
this.contextMenuID = contextMenuID; |
this.editor = editor; |
@@ -229,8 +449,8 @@ public class DartOutlinePage extends Page implements IContentOutlinePage { |
// create "viewer" |
viewer = new DartOutlineViewer(tree); |
ColoredViewersManager.install(viewer); |
- viewer.setContentProvider(LightNodeElements.newTreeContentProvider(editor)); |
- viewer.setLabelProvider(LightNodeElements.newLabelProvider()); |
+ viewer.setContentProvider(new OutlineContentProvider()); |
+ viewer.setLabelProvider(new DelegatingStyledCellLabelProvider(new OutlineLabelProvider())); |
SWTUtil.bindJFaceResourcesFontToControl(tree); |
// install listeners added before UI creation |
{ |
@@ -288,17 +508,6 @@ public class DartOutlinePage extends Page implements IContentOutlinePage { |
// update colors |
preferences.addPropertyChangeListener(propertyChangeListener); |
viewer.updateColors(); |
- // schedule update in 100ms from now, to make impression that editor opens instantaneously |
- new UIJob("Update Outline") { |
- @Override |
- public IStatus runInUIThread(IProgressMonitor monitor) { |
- if (viewer != null) { |
- viewer.setInput(input); |
- //LightNodeElements.expandTreeItemsTimeBoxed(viewer, 75L * 1000000L); |
- } |
- return Status.OK_STATUS; |
- } |
- }.schedule(); |
} |
@Override |
@@ -357,12 +566,13 @@ public class DartOutlinePage extends Page implements IContentOutlinePage { |
} |
} |
- public void select(final LightNodeElement element) { |
+ public void select(final int offset) { |
updateViewerWithoutDraw(new Runnable() { |
@Override |
public void run() { |
- setSelection(new StructuredSelection(element)); |
- viewer.reveal(element); |
+ // TODO(scheglov) Analysis Server: add source range |
+// setSelection(new StructuredSelection(element)); |
+// viewer.reveal(element); |
} |
}); |
} |
@@ -374,7 +584,7 @@ public class DartOutlinePage extends Page implements IContentOutlinePage { |
} |
} |
- public void setInput(final CompilationUnit input) { |
+ public void setInput(final Outline input) { |
this.input = input; |
updateViewerWithoutDraw(new Runnable() { |
@Override |
@@ -406,9 +616,7 @@ public class DartOutlinePage extends Page implements IContentOutlinePage { |
protected void toggleExpansion(ISelection selection) { |
if (selection instanceof IStructuredSelection) { |
Object sel = ((IStructuredSelection) selection).getFirstElement(); |
- |
boolean expanded = viewer.getExpandedState(sel); |
- |
if (expanded) { |
viewer.collapseToLevel(sel, 1); |
} else { |