Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(471)

Unified Diff: editor/tools/plugins/com.google.dart.tools.ui/src/com/google/dart/tools/ui/internal/text/editor/DartEditor.java

Issue 11364134: Merge libv1. (Closed) Base URL: https://dart.googlecode.com/svn/experimental/lib_v2/dart
Patch Set: Reupload due to error Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: editor/tools/plugins/com.google.dart.tools.ui/src/com/google/dart/tools/ui/internal/text/editor/DartEditor.java
diff --git a/editor/tools/plugins/com.google.dart.tools.ui/src/com/google/dart/tools/ui/internal/text/editor/DartEditor.java b/editor/tools/plugins/com.google.dart.tools.ui/src/com/google/dart/tools/ui/internal/text/editor/DartEditor.java
index c2de6103c30b5846927e9bf12fe17f866d792acd..309ca5c5f7756e8f1d87ed2f416783f77c4d0bfb 100644
--- a/editor/tools/plugins/com.google.dart.tools.ui/src/com/google/dart/tools/ui/internal/text/editor/DartEditor.java
+++ b/editor/tools/plugins/com.google.dart.tools.ui/src/com/google/dart/tools/ui/internal/text/editor/DartEditor.java
@@ -28,6 +28,7 @@ import com.google.dart.tools.core.model.SourceReference;
import com.google.dart.tools.core.utilities.ast.DartElementLocator;
import com.google.dart.tools.core.utilities.ast.NameOccurrencesFinder;
import com.google.dart.tools.core.utilities.compiler.DartCompilerUtilities;
+import com.google.dart.tools.core.utilities.general.Timer;
import com.google.dart.tools.ui.DartToolsPlugin;
import com.google.dart.tools.ui.DartX;
import com.google.dart.tools.ui.IContextMenuConstants;
@@ -200,1274 +201,1274 @@ public abstract class DartEditor extends AbstractDecoratedTextEditor implements
IViewPartInputProvider {
/**
- * Internal implementation class for a change listener.
+ * Adapts an options {@link IEclipsePreferences} to
+ * {@link org.eclipse.jface.preference.IPreferenceStore}.
+ * <p>
+ * This preference store is read-only i.e. write access throws an
+ * {@link java.lang.UnsupportedOperationException}.
+ * </p>
*/
- protected abstract class AbstractSelectionChangedListener implements ISelectionChangedListener {
+ public static class EclipsePreferencesAdapter implements IPreferenceStore {
/**
- * Installs this selection changed listener with the given selection provider. If the selection
- * provider is a post selection provider, post selection changed events are the preferred
- * choice, otherwise normal selection changed events are requested.
- *
- * @param selectionProvider
+ * Preference change listener. Listens for events preferences fires a
+ * {@link org.eclipse.jface.util.PropertyChangeEvent} on this adapter with arguments from the
+ * received event.
*/
- public void install(ISelectionProvider selectionProvider) {
- if (selectionProvider == null) {
- return;
- }
+ private class PreferenceChangeListener implements IEclipsePreferences.IPreferenceChangeListener {
- if (selectionProvider instanceof IPostSelectionProvider) {
- IPostSelectionProvider provider = (IPostSelectionProvider) selectionProvider;
- provider.addPostSelectionChangedListener(this);
- } else {
- selectionProvider.addSelectionChangedListener(this);
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void preferenceChange(final IEclipsePreferences.PreferenceChangeEvent event) {
+ if (Display.getCurrent() == null) {
+ Display.getDefault().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ firePropertyChangeEvent(event.getKey(), event.getOldValue(), event.getNewValue());
+ }
+ });
+ } else {
+ firePropertyChangeEvent(event.getKey(), event.getOldValue(), event.getNewValue());
+ }
}
}
+ /** Listeners on on this adapter */
+ private final ListenerList fListeners = new ListenerList(ListenerList.IDENTITY);
+
+ /** Listener on the node */
+ private final IEclipsePreferences.IPreferenceChangeListener fListener = new PreferenceChangeListener();
+
+ /** wrapped node */
+ private final IScopeContext fContext;
+ private final String fQualifier;
+
/**
- * Removes this selection changed listener from the given selection provider.
+ * Initialize with the node to wrap
*
- * @param selectionProvider the selection provider
+ * @param context the context to access
+ * @param qualifier the qualifier
*/
- public void uninstall(ISelectionProvider selectionProvider) {
- if (selectionProvider == null) {
- return;
- }
-
- if (selectionProvider instanceof IPostSelectionProvider) {
- IPostSelectionProvider provider = (IPostSelectionProvider) selectionProvider;
- provider.removePostSelectionChangedListener(this);
- } else {
- selectionProvider.removeSelectionChangedListener(this);
- }
+ public EclipsePreferencesAdapter(IScopeContext context, String qualifier) {
+ fContext = context;
+ fQualifier = qualifier;
}
- }
-
- /**
- * Text operation action to delete the next sub-word.
- */
- protected class DeleteNextSubWordAction extends NextSubWordAction implements IUpdate {
/**
- * Creates a new delete next sub-word action.
+ * {@inheritDoc}
*/
- public DeleteNextSubWordAction() {
- super(ST.DELETE_WORD_NEXT);
+ @Override
+ public void addPropertyChangeListener(IPropertyChangeListener listener) {
+ if (fListeners.size() == 0) {
+ getNode().addPreferenceChangeListener(fListener);
+ }
+ fListeners.add(listener);
}
- /*
- * @see org.eclipse.ui.texteditor.IUpdate#update()
+ /**
+ * {@inheritDoc}
*/
@Override
- public void update() {
- setEnabled(isEditorInputModifiable());
+ public boolean contains(String name) {
+ return getNode().get(name, null) != null;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- protected void setCaretPosition(final int position) {
- if (!validateEditorInputState()) {
- return;
- }
-
- final ISourceViewer viewer = getSourceViewer();
- StyledText text = viewer.getTextWidget();
- Point widgetSelection = text.getSelection();
- if (isBlockSelectionModeEnabled() && widgetSelection.y != widgetSelection.x) {
- final int caret = text.getCaretOffset();
- final int offset = modelOffset2WidgetOffset(viewer, position);
-
- if (caret == widgetSelection.x) {
- text.setSelectionRange(widgetSelection.y, offset - widgetSelection.y);
- } else {
- text.setSelectionRange(widgetSelection.x, offset - widgetSelection.x);
- }
- text.invokeAction(ST.DELETE_NEXT);
- } else {
- Point selection = viewer.getSelectedRange();
- final int caret, length;
- if (selection.y != 0) {
- caret = selection.x;
- length = selection.y;
- } else {
- caret = widgetOffset2ModelOffset(viewer, text.getCaretOffset());
- length = position - caret;
- }
-
- try {
- viewer.getDocument().replace(caret, length, ""); //$NON-NLS-1$
- } catch (BadLocationException exception) {
- // Should not happen
- }
+ public void firePropertyChangeEvent(String name, Object oldValue, Object newValue) {
+ PropertyChangeEvent event = new PropertyChangeEvent(this, name, oldValue, newValue);
+ Object[] listeners = fListeners.getListeners();
+ for (int i = 0; i < listeners.length; i++) {
+ ((IPropertyChangeListener) listeners[i]).propertyChange(event);
}
}
- }
-
- /**
- * Text operation action to delete the previous sub-word.
- */
- protected class DeletePreviousSubWordAction extends PreviousSubWordAction implements IUpdate {
/**
- * Creates a new delete previous sub-word action.
+ * {@inheritDoc}
*/
- public DeletePreviousSubWordAction() {
- super(ST.DELETE_WORD_PREVIOUS);
+ @Override
+ public boolean getBoolean(String name) {
+ return getNode().getBoolean(name, BOOLEAN_DEFAULT_DEFAULT);
}
- /*
- * @see org.eclipse.ui.texteditor.IUpdate#update()
+ /**
+ * {@inheritDoc}
*/
@Override
- public void update() {
- setEnabled(isEditorInputModifiable());
+ public boolean getDefaultBoolean(String name) {
+ return BOOLEAN_DEFAULT_DEFAULT;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- protected void setCaretPosition(int position) {
- if (!validateEditorInputState()) {
- return;
- }
-
- final int length;
- final ISourceViewer viewer = getSourceViewer();
- StyledText text = viewer.getTextWidget();
- Point widgetSelection = text.getSelection();
- if (isBlockSelectionModeEnabled() && widgetSelection.y != widgetSelection.x) {
- final int caret = text.getCaretOffset();
- final int offset = modelOffset2WidgetOffset(viewer, position);
+ public double getDefaultDouble(String name) {
+ return DOUBLE_DEFAULT_DEFAULT;
+ }
- if (caret == widgetSelection.x) {
- text.setSelectionRange(widgetSelection.y, offset - widgetSelection.y);
- } else {
- text.setSelectionRange(widgetSelection.x, offset - widgetSelection.x);
- }
- text.invokeAction(ST.DELETE_PREVIOUS);
- } else {
- Point selection = viewer.getSelectedRange();
- if (selection.y != 0) {
- position = selection.x;
- length = selection.y;
- } else {
- length = widgetOffset2ModelOffset(viewer, text.getCaretOffset()) - position;
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public float getDefaultFloat(String name) {
+ return FLOAT_DEFAULT_DEFAULT;
+ }
- try {
- viewer.getDocument().replace(position, length, ""); //$NON-NLS-1$
- } catch (BadLocationException exception) {
- // Should not happen
- }
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getDefaultInt(String name) {
+ return INT_DEFAULT_DEFAULT;
}
- }
- /**
- * Format element action to format the enclosing Dart element.
- * <p>
- * The format element action works as follows:
- * <ul>
- * <li>If there is no selection and the caret is positioned on a Dart element, only this element
- * is formatted. If the element has some accompanying comment, then the comment is formatted as
- * well.</li>
- * <li>If the selection spans one or more partitions of the document, then all partitions covered
- * by the selection are entirely formatted.</li>
- * <p>
- * Partitions at the end of the selection are not completed, except for comments.
- */
- protected class FormatElementAction extends Action implements IUpdate {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public long getDefaultLong(String name) {
+ return LONG_DEFAULT_DEFAULT;
+ }
- /*
- *
+ /**
+ * {@inheritDoc}
*/
- FormatElementAction() {
- setEnabled(isEditorInputModifiable());
+ @Override
+ public String getDefaultString(String name) {
+ return STRING_DEFAULT_DEFAULT;
}
- /*
- * @see org.eclipse.jface.action.IAction#run()
+ /**
+ * {@inheritDoc}
*/
@Override
- public void run() {
+ public double getDouble(String name) {
+ return getNode().getDouble(name, DOUBLE_DEFAULT_DEFAULT);
+ }
- final DartSourceViewer viewer = (DartSourceViewer) getSourceViewer();
- if (viewer.isEditable()) {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public float getFloat(String name) {
+ return getNode().getFloat(name, FLOAT_DEFAULT_DEFAULT);
+ }
- final Point selection = viewer.rememberSelection();
- try {
- viewer.setRedraw(false);
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int getInt(String name) {
+ return getNode().getInt(name, INT_DEFAULT_DEFAULT);
+ }
- final String type = TextUtilities.getContentType(
- viewer.getDocument(),
- DartPartitions.DART_PARTITIONING,
- selection.x,
- true);
- if (type.equals(IDocument.DEFAULT_CONTENT_TYPE) && selection.y == 0) {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public long getLong(String name) {
+ return getNode().getLong(name, LONG_DEFAULT_DEFAULT);
+ }
- try {
- final DartElement element = getElementAt(selection.x, true);
- if (element != null && element.exists()) {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getString(String name) {
+ return getNode().get(name, STRING_DEFAULT_DEFAULT);
+ }
- final int kind = element.getElementType();
- if (kind == DartElement.TYPE || kind == DartElement.METHOD) {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isDefault(String name) {
+ return false;
+ }
- final SourceReference reference = (SourceReference) element;
- final SourceRange range = reference.getSourceRange();
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean needsSaving() {
+ try {
+ return getNode().keys().length > 0;
+ } catch (BackingStoreException e) {
+ // ignore
+ }
+ return true;
+ }
- if (range != null) {
- viewer.setSelectedRange(range.getOffset(), range.getLength());
- viewer.doOperation(ISourceViewer.FORMAT);
- }
- }
- }
- } catch (DartModelException exception) {
- // Should not happen
- }
- } else {
- viewer.setSelectedRange(selection.x, 1);
- viewer.doOperation(ISourceViewer.FORMAT);
- }
- } catch (BadLocationException exception) {
- // Can not happen
- } finally {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void putValue(String name, String value) {
+ throw new UnsupportedOperationException();
+ }
- viewer.setRedraw(true);
- viewer.restoreSelection();
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void removePropertyChangeListener(IPropertyChangeListener listener) {
+ fListeners.remove(listener);
+ if (fListeners.size() == 0) {
+ getNode().removePreferenceChangeListener(fListener);
}
}
- /*
- * @see org.eclipse.ui.texteditor.IUpdate#update()
+ /**
+ * {@inheritDoc}
*/
@Override
- public void update() {
- setEnabled(isEditorInputModifiable());
+ public void setDefault(String name, boolean value) {
+ throw new UnsupportedOperationException();
}
- }
- /**
- * Text navigation action to navigate to the next sub-word.
- */
- protected class NavigateNextSubWordAction extends NextSubWordAction {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setDefault(String name, double value) {
+ throw new UnsupportedOperationException();
+ }
/**
- * Creates a new navigate next sub-word action.
+ * {@inheritDoc}
*/
- public NavigateNextSubWordAction() {
- super(ST.WORD_NEXT);
+ @Override
+ public void setDefault(String name, float value) {
+ throw new UnsupportedOperationException();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- protected void setCaretPosition(final int position) {
- getTextWidget().setCaretOffset(modelOffset2WidgetOffset(getSourceViewer(), position));
+ public void setDefault(String name, int value) {
+ throw new UnsupportedOperationException();
}
- }
- /**
- * Text navigation action to navigate to the previous sub-word.
- */
- protected class NavigatePreviousSubWordAction extends PreviousSubWordAction {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setDefault(String name, long value) {
+ throw new UnsupportedOperationException();
+ }
/**
- * Creates a new navigate previous sub-word action.
+ * {@inheritDoc}
*/
- public NavigatePreviousSubWordAction() {
- super(ST.WORD_PREVIOUS);
+ @Override
+ public void setDefault(String name, String defaultObject) {
+ throw new UnsupportedOperationException();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
- protected void setCaretPosition(final int position) {
- getTextWidget().setCaretOffset(modelOffset2WidgetOffset(getSourceViewer(), position));
+ public void setToDefault(String name) {
+ throw new UnsupportedOperationException();
}
- }
- /**
- * Text navigation action to navigate to the next sub-word.
- */
- protected abstract class NextSubWordAction extends TextNavigationAction {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setValue(String name, boolean value) {
+ throw new UnsupportedOperationException();
+ }
- protected DartWordIterator fIterator = new DartWordIterator();
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setValue(String name, double value) {
+ throw new UnsupportedOperationException();
+ }
/**
- * Creates a new next sub-word action.
- *
- * @param code Action code for the default operation. Must be an action code from @see
- * org.eclipse.swt.custom.ST.
+ * {@inheritDoc}
*/
- protected NextSubWordAction(int code) {
- super(getSourceViewer().getTextWidget(), code);
+ @Override
+ public void setValue(String name, float value) {
+ throw new UnsupportedOperationException();
}
- /*
- * @see org.eclipse.jface.action.IAction#run()
+ /**
+ * {@inheritDoc}
*/
@Override
- public void run() {
- // Check whether we are in a Dart code partition and the preference is enabled
- final IPreferenceStore store = getPreferenceStore();
- if (!store.getBoolean(PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION)) {
- super.run();
- return;
- }
+ public void setValue(String name, int value) {
+ throw new UnsupportedOperationException();
+ }
- final ISourceViewer viewer = getSourceViewer();
- final IDocument document = viewer.getDocument();
- fIterator.setText((CharacterIterator) new DocumentCharacterIterator(document));
- int position = widgetOffset2ModelOffset(viewer, viewer.getTextWidget().getCaretOffset());
- if (position == -1) {
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setValue(String name, long value) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setValue(String name, String value) {
+ throw new UnsupportedOperationException();
+ }
+
+ protected IEclipsePreferences getNode() {
+ return fContext.getNode(fQualifier);
+ }
+
+ }
+
+ /**
+ * Internal implementation class for a change listener.
+ */
+ protected abstract class AbstractSelectionChangedListener implements ISelectionChangedListener {
+
+ /**
+ * Installs this selection changed listener with the given selection provider. If the selection
+ * provider is a post selection provider, post selection changed events are the preferred
+ * choice, otherwise normal selection changed events are requested.
+ *
+ * @param selectionProvider
+ */
+ public void install(ISelectionProvider selectionProvider) {
+ if (selectionProvider == null) {
return;
}
- int next = findNextPosition(position);
- try {
- if (isBlockSelectionModeEnabled()
- && document.getLineOfOffset(next) != document.getLineOfOffset(position)) {
- super.run(); // may navigate into virtual white space
- } else if (next != BreakIterator.DONE) {
- setCaretPosition(next);
- getTextWidget().showSelection();
- fireSelectionChanged();
- }
- } catch (BadLocationException x) {
- // ignore
+ if (selectionProvider instanceof IPostSelectionProvider) {
+ IPostSelectionProvider provider = (IPostSelectionProvider) selectionProvider;
+ provider.addPostSelectionChangedListener(this);
+ } else {
+ selectionProvider.addSelectionChangedListener(this);
}
}
/**
- * Finds the next position after the given position.
+ * Removes this selection changed listener from the given selection provider.
*
- * @param position the current position
- * @return the next position
+ * @param selectionProvider the selection provider
*/
- protected int findNextPosition(int position) {
- ISourceViewer viewer = getSourceViewer();
- int widget = -1;
- int next = position;
- while (next != BreakIterator.DONE && widget == -1) { // TODO: optimize
- next = fIterator.following(next);
- if (next != BreakIterator.DONE) {
- widget = modelOffset2WidgetOffset(viewer, next);
- }
+ public void uninstall(ISelectionProvider selectionProvider) {
+ if (selectionProvider == null) {
+ return;
}
- IDocument document = viewer.getDocument();
- LinkedModeModel model = LinkedModeModel.getModel(document, position);
- if (model != null) {
- LinkedPosition linkedPosition = model.findPosition(new LinkedPosition(document, position, 0));
- if (linkedPosition != null) {
- int linkedPositionEnd = linkedPosition.getOffset() + linkedPosition.getLength();
- if (position != linkedPositionEnd && linkedPositionEnd < next) {
- next = linkedPositionEnd;
- }
- } else {
- LinkedPosition nextLinkedPosition = model.findPosition(new LinkedPosition(
- document,
- next,
- 0));
- if (nextLinkedPosition != null) {
- int nextLinkedPositionOffset = nextLinkedPosition.getOffset();
- if (position != nextLinkedPositionOffset && nextLinkedPositionOffset < next) {
- next = nextLinkedPositionOffset;
- }
- }
- }
+ if (selectionProvider instanceof IPostSelectionProvider) {
+ IPostSelectionProvider provider = (IPostSelectionProvider) selectionProvider;
+ provider.removePostSelectionChangedListener(this);
+ } else {
+ selectionProvider.removeSelectionChangedListener(this);
}
-
- return next;
}
-
- /**
- * Sets the caret position to the sub-word boundary given with <code>position</code>.
- *
- * @param position Position where the action should move the caret
- */
- protected abstract void setCaretPosition(int position);
}
/**
- * Text navigation action to navigate to the previous sub-word.
+ * Text operation action to delete the next sub-word.
*/
- protected abstract class PreviousSubWordAction extends TextNavigationAction {
-
- protected DartWordIterator fIterator = new DartWordIterator();
+ protected class DeleteNextSubWordAction extends NextSubWordAction implements IUpdate {
/**
- * Creates a new previous sub-word action.
- *
- * @param code Action code for the default operation. Must be an action code from @see
- * org.eclipse.swt.custom.ST.
+ * Creates a new delete next sub-word action.
*/
- protected PreviousSubWordAction(final int code) {
- super(getSourceViewer().getTextWidget(), code);
+ public DeleteNextSubWordAction() {
+ super(ST.DELETE_WORD_NEXT);
}
/*
- * @see org.eclipse.jface.action.IAction#run()
+ * @see org.eclipse.ui.texteditor.IUpdate#update()
*/
@Override
- public void run() {
- // Check whether we are in a Dart code partition and the preference is enabled
- final IPreferenceStore store = getPreferenceStore();
- if (!store.getBoolean(PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION)) {
- super.run();
+ public void update() {
+ setEnabled(isEditorInputModifiable());
+ }
+
+ @Override
+ protected void setCaretPosition(final int position) {
+ if (!validateEditorInputState()) {
return;
}
final ISourceViewer viewer = getSourceViewer();
- final IDocument document = viewer.getDocument();
- fIterator.setText((CharacterIterator) new DocumentCharacterIterator(document));
- int position = widgetOffset2ModelOffset(viewer, viewer.getTextWidget().getCaretOffset());
- if (position == -1) {
- return;
- }
+ StyledText text = viewer.getTextWidget();
+ Point widgetSelection = text.getSelection();
+ if (isBlockSelectionModeEnabled() && widgetSelection.y != widgetSelection.x) {
+ final int caret = text.getCaretOffset();
+ final int offset = modelOffset2WidgetOffset(viewer, position);
- int previous = findPreviousPosition(position);
- try {
- if (isBlockSelectionModeEnabled()
- && document.getLineOfOffset(previous) != document.getLineOfOffset(position)) {
- super.run(); // may navigate into virtual white space
- } else if (previous != BreakIterator.DONE) {
- setCaretPosition(previous);
- getTextWidget().showSelection();
- fireSelectionChanged();
+ if (caret == widgetSelection.x) {
+ text.setSelectionRange(widgetSelection.y, offset - widgetSelection.y);
+ } else {
+ text.setSelectionRange(widgetSelection.x, offset - widgetSelection.x);
}
- } catch (BadLocationException x) {
- // ignore - getLineOfOffset failed
- }
-
- }
-
- /**
- * Finds the previous position before the given position.
- *
- * @param position the current position
- * @return the previous position
- */
- protected int findPreviousPosition(int position) {
- ISourceViewer viewer = getSourceViewer();
- int widget = -1;
- int previous = position;
- while (previous != BreakIterator.DONE && widget == -1) { // TODO: optimize
- previous = fIterator.preceding(previous);
- if (previous != BreakIterator.DONE) {
- widget = modelOffset2WidgetOffset(viewer, previous);
+ text.invokeAction(ST.DELETE_NEXT);
+ } else {
+ Point selection = viewer.getSelectedRange();
+ final int caret, length;
+ if (selection.y != 0) {
+ caret = selection.x;
+ length = selection.y;
+ } else {
+ caret = widgetOffset2ModelOffset(viewer, text.getCaretOffset());
+ length = position - caret;
}
- }
- IDocument document = viewer.getDocument();
- LinkedModeModel model = LinkedModeModel.getModel(document, position);
- if (model != null) {
- LinkedPosition linkedPosition = model.findPosition(new LinkedPosition(document, position, 0));
- if (linkedPosition != null) {
- int linkedPositionOffset = linkedPosition.getOffset();
- if (position != linkedPositionOffset && previous < linkedPositionOffset) {
- previous = linkedPositionOffset;
- }
- } else {
- LinkedPosition previousLinkedPosition = model.findPosition(new LinkedPosition(
- document,
- previous,
- 0));
- if (previousLinkedPosition != null) {
- int previousLinkedPositionEnd = previousLinkedPosition.getOffset()
- + previousLinkedPosition.getLength();
- if (position != previousLinkedPositionEnd && previous < previousLinkedPositionEnd) {
- previous = previousLinkedPositionEnd;
- }
- }
+ try {
+ viewer.getDocument().replace(caret, length, ""); //$NON-NLS-1$
+ } catch (BadLocationException exception) {
+ // Should not happen
}
}
-
- return previous;
}
-
- /**
- * Sets the caret position to the sub-word boundary given with <code>position</code>.
- *
- * @param position Position where the action should move the caret
- */
- protected abstract void setCaretPosition(int position);
}
/**
- * Text operation action to select the next sub-word.
+ * Text operation action to delete the previous sub-word.
*/
- protected class SelectNextSubWordAction extends NextSubWordAction {
+ protected class DeletePreviousSubWordAction extends PreviousSubWordAction implements IUpdate {
/**
- * Creates a new select next sub-word action.
+ * Creates a new delete previous sub-word action.
*/
- public SelectNextSubWordAction() {
- super(ST.SELECT_WORD_NEXT);
+ public DeletePreviousSubWordAction() {
+ super(ST.DELETE_WORD_PREVIOUS);
}
+ /*
+ * @see org.eclipse.ui.texteditor.IUpdate#update()
+ */
@Override
- protected void setCaretPosition(final int position) {
- final ISourceViewer viewer = getSourceViewer();
+ public void update() {
+ setEnabled(isEditorInputModifiable());
+ }
- final StyledText text = viewer.getTextWidget();
- if (text != null && !text.isDisposed()) {
+ @Override
+ protected void setCaretPosition(int position) {
+ if (!validateEditorInputState()) {
+ return;
+ }
- final Point selection = text.getSelection();
+ final int length;
+ final ISourceViewer viewer = getSourceViewer();
+ StyledText text = viewer.getTextWidget();
+ Point widgetSelection = text.getSelection();
+ if (isBlockSelectionModeEnabled() && widgetSelection.y != widgetSelection.x) {
final int caret = text.getCaretOffset();
final int offset = modelOffset2WidgetOffset(viewer, position);
- if (caret == selection.x) {
- text.setSelectionRange(selection.y, offset - selection.y);
+ if (caret == widgetSelection.x) {
+ text.setSelectionRange(widgetSelection.y, offset - widgetSelection.y);
} else {
- text.setSelectionRange(selection.x, offset - selection.x);
+ text.setSelectionRange(widgetSelection.x, offset - widgetSelection.x);
+ }
+ text.invokeAction(ST.DELETE_PREVIOUS);
+ } else {
+ Point selection = viewer.getSelectedRange();
+ if (selection.y != 0) {
+ position = selection.x;
+ length = selection.y;
+ } else {
+ length = widgetOffset2ModelOffset(viewer, text.getCaretOffset()) - position;
+ }
+
+ try {
+ viewer.getDocument().replace(position, length, ""); //$NON-NLS-1$
+ } catch (BadLocationException exception) {
+ // Should not happen
}
}
}
}
/**
- * Text operation action to select the previous sub-word.
+ * Format element action to format the enclosing Dart element.
+ * <p>
+ * The format element action works as follows:
+ * <ul>
+ * <li>If there is no selection and the caret is positioned on a Dart element, only this element
+ * is formatted. If the element has some accompanying comment, then the comment is formatted as
+ * well.</li>
+ * <li>If the selection spans one or more partitions of the document, then all partitions covered
+ * by the selection are entirely formatted.</li>
+ * <p>
+ * Partitions at the end of the selection are not completed, except for comments.
*/
- protected class SelectPreviousSubWordAction extends PreviousSubWordAction {
+ protected class FormatElementAction extends Action implements IUpdate {
- /**
- * Creates a new select previous sub-word action.
+ /*
+ *
*/
- public SelectPreviousSubWordAction() {
- super(ST.SELECT_WORD_PREVIOUS);
+ FormatElementAction() {
+ setEnabled(isEditorInputModifiable());
}
+ /*
+ * @see org.eclipse.jface.action.IAction#run()
+ */
@Override
- protected void setCaretPosition(final int position) {
- final ISourceViewer viewer = getSourceViewer();
+ public void run() {
- final StyledText text = viewer.getTextWidget();
- if (text != null && !text.isDisposed()) {
+ final DartSourceViewer viewer = (DartSourceViewer) getSourceViewer();
+ if (viewer.isEditable()) {
- final Point selection = text.getSelection();
- final int caret = text.getCaretOffset();
- final int offset = modelOffset2WidgetOffset(viewer, position);
+ final Point selection = viewer.rememberSelection();
+ try {
+ viewer.setRedraw(false);
- if (caret == selection.x) {
- text.setSelectionRange(selection.y, offset - selection.y);
- } else {
- text.setSelectionRange(selection.x, offset - selection.x);
+ final String type = TextUtilities.getContentType(
+ viewer.getDocument(),
+ DartPartitions.DART_PARTITIONING,
+ selection.x,
+ true);
+ if (type.equals(IDocument.DEFAULT_CONTENT_TYPE) && selection.y == 0) {
+
+ try {
+ final DartElement element = getElementAt(selection.x, true);
+ if (element != null && element.exists()) {
+
+ final int kind = element.getElementType();
+ if (kind == DartElement.TYPE || kind == DartElement.METHOD) {
+
+ final SourceReference reference = (SourceReference) element;
+ final SourceRange range = reference.getSourceRange();
+
+ if (range != null) {
+ viewer.setSelectedRange(range.getOffset(), range.getLength());
+ viewer.doOperation(ISourceViewer.FORMAT);
+ }
+ }
+ }
+ } catch (DartModelException exception) {
+ // Should not happen
+ }
+ } else {
+ viewer.setSelectedRange(selection.x, 1);
+ viewer.doOperation(ISourceViewer.FORMAT);
+ }
+ } catch (BadLocationException exception) {
+ // Can not happen
+ } finally {
+
+ viewer.setRedraw(true);
+ viewer.restoreSelection();
}
}
}
+
+ /*
+ * @see org.eclipse.ui.texteditor.IUpdate#update()
+ */
+ @Override
+ public void update() {
+ setEnabled(isEditorInputModifiable());
+ }
}
/**
- * This action implements smart home. Instead of going to the start of a line it does the
- * following: - if smart home/end is enabled and the caret is after the line's first
- * non-whitespace then the caret is moved directly before it, taking JavaDoc and multi-line
- * comments into account. - if the caret is before the line's first non-whitespace the caret is
- * moved to the beginning of the line - if the caret is at the beginning of the line see first
- * case.
+ * Text navigation action to navigate to the next sub-word.
*/
- protected class SmartLineStartAction extends LineStartAction {
+ protected class NavigateNextSubWordAction extends NextSubWordAction {
/**
- * Creates a new smart line start action
- *
- * @param textWidget the styled text widget
- * @param doSelect a boolean flag which tells if the text up to the beginning of the line should
- * be selected
+ * Creates a new navigate next sub-word action.
*/
- public SmartLineStartAction(final StyledText textWidget, final boolean doSelect) {
- super(textWidget, doSelect);
+ public NavigateNextSubWordAction() {
+ super(ST.WORD_NEXT);
}
- /*
- * @see org.eclipse.ui.texteditor.AbstractTextEditor.LineStartAction#
- * getLineStartPosition(java.lang.String, int, java.lang.String)
- */
@Override
- protected int getLineStartPosition(final IDocument document, final String line,
- final int length, final int offset) {
+ protected void setCaretPosition(final int position) {
+ getTextWidget().setCaretOffset(modelOffset2WidgetOffset(getSourceViewer(), position));
+ }
+ }
- String type = IDocument.DEFAULT_CONTENT_TYPE;
- try {
- type = TextUtilities.getContentType(
- document,
- DartPartitions.DART_PARTITIONING,
- offset,
- true);
- } catch (BadLocationException exception) {
- // Should not happen
- }
+ /**
+ * Text navigation action to navigate to the previous sub-word.
+ */
+ protected class NavigatePreviousSubWordAction extends PreviousSubWordAction {
- int index = super.getLineStartPosition(document, line, length, offset);
- if (type.equals(DartPartitions.DART_DOC)
- || type.equals(DartPartitions.DART_MULTI_LINE_COMMENT)) {
- if (index < length - 1 && line.charAt(index) == '*' && line.charAt(index + 1) != '/') {
- do {
- ++index;
- } while (index < length && Character.isWhitespace(line.charAt(index)));
- }
- } else {
- if (index < length - 1 && line.charAt(index) == '/' && line.charAt(index + 1) == '/') {
- if (type.equals(DartPartitions.DART_SINGLE_LINE_DOC)
- && (index < length - 2 && line.charAt(index + 2) == '/')) {
- index++;
- }
- index++;
- do {
- ++index;
- } while (index < length && Character.isWhitespace(line.charAt(index)));
- }
- }
- return index;
+ /**
+ * Creates a new navigate previous sub-word action.
+ */
+ public NavigatePreviousSubWordAction() {
+ super(ST.WORD_PREVIOUS);
+ }
+
+ @Override
+ protected void setCaretPosition(final int position) {
+ getTextWidget().setCaretOffset(modelOffset2WidgetOffset(getSourceViewer(), position));
}
}
/**
- * Finds and marks occurrence annotations.
+ * Text navigation action to navigate to the next sub-word.
*/
- class OccurrencesFinderJob extends Job {
-
- private final IDocument fDocument;
- private final ISelection fSelection;
- private ISelectionValidator fPostSelectionValidator;
- private boolean fCanceled = false;
- private IProgressMonitor fProgressMonitor;
- private final Position[] fPositions;
+ protected abstract class NextSubWordAction extends TextNavigationAction {
- public OccurrencesFinderJob(IDocument document, Position[] positions, ISelection selection) {
- super(DartEditorMessages.JavaEditor_markOccurrences_job_name);
- fDocument = document;
- fSelection = selection;
- fPositions = positions;
+ protected DartWordIterator fIterator = new DartWordIterator();
- if (getSelectionProvider() instanceof ISelectionValidator) {
- fPostSelectionValidator = (ISelectionValidator) getSelectionProvider();
- }
+ /**
+ * Creates a new next sub-word action.
+ *
+ * @param code Action code for the default operation. Must be an action code from @see
+ * org.eclipse.swt.custom.ST.
+ */
+ protected NextSubWordAction(int code) {
+ super(getSourceViewer().getTextWidget(), code);
}
/*
- * @see Job#run(org.eclipse.core.runtime.IProgressMonitor)
+ * @see org.eclipse.jface.action.IAction#run()
*/
@Override
- public IStatus run(IProgressMonitor progressMonitor) {
-
- fProgressMonitor = progressMonitor;
-
- if (isCanceled()) {
- return Status.CANCEL_STATUS;
+ public void run() {
+ // Check whether we are in a Dart code partition and the preference is enabled
+ final IPreferenceStore store = getPreferenceStore();
+ if (!store.getBoolean(PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION)) {
+ super.run();
+ return;
}
- ITextViewer textViewer = getViewer();
- if (textViewer == null) {
- return Status.CANCEL_STATUS;
+ final ISourceViewer viewer = getSourceViewer();
+ final IDocument document = viewer.getDocument();
+ fIterator.setText((CharacterIterator) new DocumentCharacterIterator(document));
+ int position = widgetOffset2ModelOffset(viewer, viewer.getTextWidget().getCaretOffset());
+ if (position == -1) {
+ return;
}
- IDocument document = textViewer.getDocument();
- if (document == null) {
- return Status.CANCEL_STATUS;
+ int next = findNextPosition(position);
+ try {
+ if (isBlockSelectionModeEnabled()
+ && document.getLineOfOffset(next) != document.getLineOfOffset(position)) {
+ super.run(); // may navigate into virtual white space
+ } else if (next != BreakIterator.DONE) {
+ setCaretPosition(next);
+ getTextWidget().showSelection();
+ fireSelectionChanged();
+ }
+ } catch (BadLocationException x) {
+ // ignore
}
+ }
- IDocumentProvider documentProvider = getDocumentProvider();
- if (documentProvider == null) {
- return Status.CANCEL_STATUS;
+ /**
+ * Finds the next position after the given position.
+ *
+ * @param position the current position
+ * @return the next position
+ */
+ protected int findNextPosition(int position) {
+ ISourceViewer viewer = getSourceViewer();
+ int widget = -1;
+ int next = position;
+ while (next != BreakIterator.DONE && widget == -1) { // TODO: optimize
+ next = fIterator.following(next);
+ if (next != BreakIterator.DONE) {
+ widget = modelOffset2WidgetOffset(viewer, next);
+ }
}
- IAnnotationModel annotationModel = documentProvider.getAnnotationModel(getEditorInput());
- if (annotationModel == null) {
- return Status.CANCEL_STATUS;
+ IDocument document = viewer.getDocument();
+ LinkedModeModel model = LinkedModeModel.getModel(document, position);
+ if (model != null) {
+ LinkedPosition linkedPosition = model.findPosition(new LinkedPosition(document, position, 0));
+ if (linkedPosition != null) {
+ int linkedPositionEnd = linkedPosition.getOffset() + linkedPosition.getLength();
+ if (position != linkedPositionEnd && linkedPositionEnd < next) {
+ next = linkedPositionEnd;
+ }
+ } else {
+ LinkedPosition nextLinkedPosition = model.findPosition(new LinkedPosition(
+ document,
+ next,
+ 0));
+ if (nextLinkedPosition != null) {
+ int nextLinkedPositionOffset = nextLinkedPosition.getOffset();
+ if (position != nextLinkedPositionOffset && nextLinkedPositionOffset < next) {
+ next = nextLinkedPositionOffset;
+ }
+ }
+ }
}
- // Add occurrence annotations
- int length = fPositions.length;
- Map<Annotation, Position> annotationMap = new HashMap<Annotation, Position>(length);
- for (int i = 0; i < length; i++) {
+ return next;
+ }
- if (isCanceled()) {
- return Status.CANCEL_STATUS;
- }
+ /**
+ * Sets the caret position to the sub-word boundary given with <code>position</code>.
+ *
+ * @param position Position where the action should move the caret
+ */
+ protected abstract void setCaretPosition(int position);
+ }
- String message;
- Position position = fPositions[i];
+ /**
+ * Text navigation action to navigate to the previous sub-word.
+ */
+ protected abstract class PreviousSubWordAction extends TextNavigationAction {
- // Create & add annotation
- try {
- message = document.get(position.offset, position.length);
- } catch (BadLocationException ex) {
- // Skip this match
- continue;
+ protected DartWordIterator fIterator = new DartWordIterator();
+
+ /**
+ * Creates a new previous sub-word action.
+ *
+ * @param code Action code for the default operation. Must be an action code from @see
+ * org.eclipse.swt.custom.ST.
+ */
+ protected PreviousSubWordAction(final int code) {
+ super(getSourceViewer().getTextWidget(), code);
+ }
+
+ /*
+ * @see org.eclipse.jface.action.IAction#run()
+ */
+ @Override
+ public void run() {
+ // Check whether we are in a Dart code partition and the preference is enabled
+ final IPreferenceStore store = getPreferenceStore();
+ if (!store.getBoolean(PreferenceConstants.EDITOR_SUB_WORD_NAVIGATION)) {
+ super.run();
+ return;
+ }
+
+ final ISourceViewer viewer = getSourceViewer();
+ final IDocument document = viewer.getDocument();
+ fIterator.setText((CharacterIterator) new DocumentCharacterIterator(document));
+ int position = widgetOffset2ModelOffset(viewer, viewer.getTextWidget().getCaretOffset());
+ if (position == -1) {
+ return;
+ }
+
+ int previous = findPreviousPosition(position);
+ try {
+ if (isBlockSelectionModeEnabled()
+ && document.getLineOfOffset(previous) != document.getLineOfOffset(position)) {
+ super.run(); // may navigate into virtual white space
+ } else if (previous != BreakIterator.DONE) {
+ setCaretPosition(previous);
+ getTextWidget().showSelection();
+ fireSelectionChanged();
}
- annotationMap.put(new Annotation("com.google.dart.tools.ui.occurrences", false, message), //$NON-NLS-1$
- position);
+ } catch (BadLocationException x) {
+ // ignore - getLineOfOffset failed
}
- if (isCanceled()) {
- return Status.CANCEL_STATUS;
+ }
+
+ /**
+ * Finds the previous position before the given position.
+ *
+ * @param position the current position
+ * @return the previous position
+ */
+ protected int findPreviousPosition(int position) {
+ ISourceViewer viewer = getSourceViewer();
+ int widget = -1;
+ int previous = position;
+ while (previous != BreakIterator.DONE && widget == -1) { // TODO: optimize
+ previous = fIterator.preceding(previous);
+ if (previous != BreakIterator.DONE) {
+ widget = modelOffset2WidgetOffset(viewer, previous);
+ }
}
- synchronized (getLockObject(annotationModel)) {
- if (annotationModel instanceof IAnnotationModelExtension) {
- ((IAnnotationModelExtension) annotationModel).replaceAnnotations(
- fOccurrenceAnnotations,
- annotationMap);
+ IDocument document = viewer.getDocument();
+ LinkedModeModel model = LinkedModeModel.getModel(document, position);
+ if (model != null) {
+ LinkedPosition linkedPosition = model.findPosition(new LinkedPosition(document, position, 0));
+ if (linkedPosition != null) {
+ int linkedPositionOffset = linkedPosition.getOffset();
+ if (position != linkedPositionOffset && previous < linkedPositionOffset) {
+ previous = linkedPositionOffset;
+ }
} else {
- removeOccurrenceAnnotations();
- Iterator<Map.Entry<Annotation, Position>> iter = annotationMap.entrySet().iterator();
- while (iter.hasNext()) {
- Map.Entry<Annotation, Position> mapEntry = iter.next();
- annotationModel.addAnnotation(mapEntry.getKey(), mapEntry.getValue());
+ LinkedPosition previousLinkedPosition = model.findPosition(new LinkedPosition(
+ document,
+ previous,
+ 0));
+ if (previousLinkedPosition != null) {
+ int previousLinkedPositionEnd = previousLinkedPosition.getOffset()
+ + previousLinkedPosition.getLength();
+ if (position != previousLinkedPositionEnd && previous < previousLinkedPositionEnd) {
+ previous = previousLinkedPositionEnd;
+ }
}
}
- fOccurrenceAnnotations = annotationMap.keySet().toArray(
- new Annotation[annotationMap.keySet().size()]);
}
- return Status.OK_STATUS;
- }
-
- // cannot use cancel() because it is declared final
- void doCancel() {
- fCanceled = true;
- cancel();
+ return previous;
}
- private boolean isCanceled() {
- return fCanceled
- || fProgressMonitor.isCanceled()
- || fPostSelectionValidator != null
- && !(fPostSelectionValidator.isValid(fSelection) || fForcedMarkOccurrencesSelection == fSelection)
- || LinkedModeModel.hasInstalledModel(fDocument);
- }
+ /**
+ * Sets the caret position to the sub-word boundary given with <code>position</code>.
+ *
+ * @param position Position where the action should move the caret
+ */
+ protected abstract void setCaretPosition(int position);
}
/**
- * Cancels the occurrences finder job upon document changes.
+ * Text operation action to select the next sub-word.
*/
- class OccurrencesFinderJobCanceler implements IDocumentListener, ITextInputListener {
+ protected class SelectNextSubWordAction extends NextSubWordAction {
- /*
- * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org
- * .eclipse.jface.text.DocumentEvent)
+ /**
+ * Creates a new select next sub-word action.
*/
- @Override
- public void documentAboutToBeChanged(DocumentEvent event) {
- if (fOccurrencesFinderJob != null) {
- fOccurrencesFinderJob.doCancel();
- }
+ public SelectNextSubWordAction() {
+ super(ST.SELECT_WORD_NEXT);
}
- /*
- * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.
- * jface.text.DocumentEvent)
- */
@Override
- public void documentChanged(DocumentEvent event) {
- }
+ protected void setCaretPosition(final int position) {
+ final ISourceViewer viewer = getSourceViewer();
- /*
- * @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged
- * (org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument)
- */
- @Override
- public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
- if (oldInput == null) {
- return;
- }
+ final StyledText text = viewer.getTextWidget();
+ if (text != null && !text.isDisposed()) {
- oldInput.removeDocumentListener(this);
- }
+ final Point selection = text.getSelection();
+ final int caret = text.getCaretOffset();
+ final int offset = modelOffset2WidgetOffset(viewer, position);
- /*
- * @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse
- * .jface.text.IDocument, org.eclipse.jface.text.IDocument)
- */
- @Override
- public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
- if (newInput == null) {
- return;
+ if (caret == selection.x) {
+ text.setSelectionRange(selection.y, offset - selection.y);
+ } else {
+ text.setSelectionRange(selection.x, offset - selection.x);
+ }
}
- newInput.addDocumentListener(this);
}
+ }
- public void install() {
- ISourceViewer sourceViewer = getSourceViewer();
- if (sourceViewer == null) {
- return;
- }
+ /**
+ * Text operation action to select the previous sub-word.
+ */
+ protected class SelectPreviousSubWordAction extends PreviousSubWordAction {
- StyledText text = sourceViewer.getTextWidget();
- if (text == null || text.isDisposed()) {
- return;
- }
+ /**
+ * Creates a new select previous sub-word action.
+ */
+ public SelectPreviousSubWordAction() {
+ super(ST.SELECT_WORD_PREVIOUS);
+ }
- sourceViewer.addTextInputListener(this);
+ @Override
+ protected void setCaretPosition(final int position) {
+ final ISourceViewer viewer = getSourceViewer();
- IDocument document = sourceViewer.getDocument();
- if (document != null) {
- document.addDocumentListener(this);
- }
- }
+ final StyledText text = viewer.getTextWidget();
+ if (text != null && !text.isDisposed()) {
- public void uninstall() {
- ISourceViewer sourceViewer = getSourceViewer();
- if (sourceViewer != null) {
- sourceViewer.removeTextInputListener(this);
- }
+ final Point selection = text.getSelection();
+ final int caret = text.getCaretOffset();
+ final int offset = modelOffset2WidgetOffset(viewer, position);
- IDocumentProvider documentProvider = getDocumentProvider();
- if (documentProvider != null) {
- IDocument document = documentProvider.getDocument(getEditorInput());
- if (document != null) {
- document.removeDocumentListener(this);
+ if (caret == selection.x) {
+ text.setSelectionRange(selection.y, offset - selection.y);
+ } else {
+ text.setSelectionRange(selection.x, offset - selection.x);
}
}
}
}
/**
- * Internal activation listener.
+ * This action implements smart home. Instead of going to the start of a line it does the
+ * following: - if smart home/end is enabled and the caret is after the line's first
+ * non-whitespace then the caret is moved directly before it, taking JavaDoc and multi-line
+ * comments into account. - if the caret is before the line's first non-whitespace the caret is
+ * moved to the beginning of the line - if the caret is at the beginning of the line see first
+ * case.
*/
- private class ActivationListener implements IWindowListener {
+ protected class SmartLineStartAction extends LineStartAction {
+
+ /**
+ * Creates a new smart line start action
+ *
+ * @param textWidget the styled text widget
+ * @param doSelect a boolean flag which tells if the text up to the beginning of the line should
+ * be selected
+ */
+ public SmartLineStartAction(final StyledText textWidget, final boolean doSelect) {
+ super(textWidget, doSelect);
+ }
/*
- * @see org.eclipse.ui.IWindowListener#windowActivated(org.eclipse.ui. IWorkbenchWindow)
+ * @see org.eclipse.ui.texteditor.AbstractTextEditor.LineStartAction#
+ * getLineStartPosition(java.lang.String, int, java.lang.String)
*/
@Override
- public void windowActivated(IWorkbenchWindow window) {
- if (window == getEditorSite().getWorkbenchWindow() && fMarkOccurrenceAnnotations
- && isActivePart()) {
- fForcedMarkOccurrencesSelection = getSelectionProvider().getSelection();
- try {
- DartElement input = getInputDartElement();
- if (input != null) {
- updateOccurrenceAnnotations(
- (ITextSelection) fForcedMarkOccurrencesSelection,
- DartToolsPlugin.getDefault().getASTProvider().getAST(
- input,
- ASTProvider.WAIT_NO,
- getProgressMonitor()));
- }
- } catch (Exception ex) {
- // ignore it
- }
- }
- }
-
- /*
- * @see org.eclipse.ui.IWindowListener#windowClosed(org.eclipse.ui.IWorkbenchWindow )
- */
- @Override
- public void windowClosed(IWorkbenchWindow window) {
- }
-
- /*
- * @see org.eclipse.ui.IWindowListener#windowDeactivated(org.eclipse.ui. IWorkbenchWindow)
- */
- @Override
- public void windowDeactivated(IWorkbenchWindow window) {
- if (window == getEditorSite().getWorkbenchWindow() && fMarkOccurrenceAnnotations
- && isActivePart()) {
- removeOccurrenceAnnotations();
- }
- }
-
- /*
- * @see org.eclipse.ui.IWindowListener#windowOpened(org.eclipse.ui.IWorkbenchWindow )
- */
- @Override
- public void windowOpened(IWorkbenchWindow window) {
- }
- }
-
- /**
- * Instances of the class <code>ASTCache</code> maintain an AST structure corresponding to the
- * contents of an editor's document.
- */
- private static class ASTCache {
- /**
- * The time at which the cache was last cleared.
- */
- private long clearTime;
-
- /**
- * The AST corresponding to the contents of the editor's document, or <code>null</code> if the
- * AST structure has not been accessed since the last time the cache was cleared.
- */
- private SoftReference<DartUnit> cachedAST;
-
- /**
- * Initialize a newly created class to be empty.
- */
- public ASTCache() {
- clearTime = 0L;
- cachedAST = null;
- }
+ protected int getLineStartPosition(final IDocument document, final String line,
+ final int length, final int offset) {
- /**
- * Clear the contents of this cache.
- */
- public void clear() {
- synchronized (this) {
- clearTime = System.nanoTime();
- cachedAST = null;
+ String type = IDocument.DEFAULT_CONTENT_TYPE;
+ try {
+ type = TextUtilities.getContentType(
+ document,
+ DartPartitions.DART_PARTITIONING,
+ offset,
+ true);
+ } catch (BadLocationException exception) {
+ // Should not happen
}
- }
- /**
- * Return the AST structure held in this cache, or <code>null</code> if the AST structure needs
- * to be created.
- *
- * @return the AST structure held in this cache
- */
- public DartUnit getAST() {
- synchronized (this) {
- if (cachedAST != null) {
- return cachedAST.get();
+ int index = super.getLineStartPosition(document, line, length, offset);
+ if (type.equals(DartPartitions.DART_DOC)
+ || type.equals(DartPartitions.DART_MULTI_LINE_COMMENT)) {
+ if (index < length - 1 && line.charAt(index) == '*' && line.charAt(index + 1) != '/') {
+ do {
+ ++index;
+ } while (index < length && Character.isWhitespace(line.charAt(index)));
}
- }
- return null;
- }
-
- /**
- * Set the AST structure held in this cache to the given AST structure provided that the cache
- * has not been cleared since the time at which the AST structure was created.
- *
- * @param creationTime the time at which the AST structure was created (in nanoseconds)
- * @param ast the AST structure that is to be cached
- */
- public void setAST(long creationTime, DartUnit ast) {
- synchronized (this) {
- if (creationTime > clearTime) {
- cachedAST = new SoftReference<DartUnit>(ast);
+ } else {
+ if (index < length - 1 && line.charAt(index) == '/' && line.charAt(index + 1) == '/') {
+ if (type.equals(DartPartitions.DART_SINGLE_LINE_DOC)
+ && (index < length - 2 && line.charAt(index + 2) == '/')) {
+ index++;
+ }
+ index++;
+ do {
+ ++index;
+ } while (index < length && Character.isWhitespace(line.charAt(index)));
}
}
+ return index;
}
}
/**
- * Adapts an options {@link IEclipsePreferences} to
- * {@link org.eclipse.jface.preference.IPreferenceStore}.
- * <p>
- * This preference store is read-only i.e. write access throws an
- * {@link java.lang.UnsupportedOperationException}.
- * </p>
+ * Finds and marks occurrence annotations.
*/
- private static class EclipsePreferencesAdapter implements IPreferenceStore {
-
- /**
- * Preference change listener. Listens for events preferences fires a
- * {@link org.eclipse.jface.util.PropertyChangeEvent} on this adapter with arguments from the
- * received event.
- */
- private class PreferenceChangeListener implements IEclipsePreferences.IPreferenceChangeListener {
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void preferenceChange(final IEclipsePreferences.PreferenceChangeEvent event) {
- if (Display.getCurrent() == null) {
- Display.getDefault().asyncExec(new Runnable() {
- @Override
- public void run() {
- firePropertyChangeEvent(event.getKey(), event.getOldValue(), event.getNewValue());
- }
- });
- } else {
- firePropertyChangeEvent(event.getKey(), event.getOldValue(), event.getNewValue());
- }
- }
- }
-
- /** Listeners on on this adapter */
- private final ListenerList fListeners = new ListenerList(ListenerList.IDENTITY);
-
- /** Listener on the node */
- private final IEclipsePreferences.IPreferenceChangeListener fListener = new PreferenceChangeListener();
+ class OccurrencesFinderJob extends Job {
- /** wrapped node */
- private final IScopeContext fContext;
- private final String fQualifier;
+ private final IDocument fDocument;
+ private final ISelection fSelection;
+ private ISelectionValidator fPostSelectionValidator;
+ private boolean fCanceled = false;
+ private IProgressMonitor fProgressMonitor;
+ private final Position[] fPositions;
- /**
- * Initialize with the node to wrap
- *
- * @param context the context to access
- * @param qualifier the qualifier
- */
- public EclipsePreferencesAdapter(IScopeContext context, String qualifier) {
- fContext = context;
- fQualifier = qualifier;
- }
+ public OccurrencesFinderJob(IDocument document, Position[] positions, ISelection selection) {
+ super(DartEditorMessages.JavaEditor_markOccurrences_job_name);
+ fDocument = document;
+ fSelection = selection;
+ fPositions = positions;
- /**
- * {@inheritDoc}
- */
- @Override
- public void addPropertyChangeListener(IPropertyChangeListener listener) {
- if (fListeners.size() == 0) {
- getNode().addPreferenceChangeListener(fListener);
+ if (getSelectionProvider() instanceof ISelectionValidator) {
+ fPostSelectionValidator = (ISelectionValidator) getSelectionProvider();
}
- fListeners.add(listener);
}
- /**
- * {@inheritDoc}
+ /*
+ * @see Job#run(org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
- public boolean contains(String name) {
- return getNode().get(name, null) != null;
- }
+ public IStatus run(IProgressMonitor progressMonitor) {
- /**
- * {@inheritDoc}
- */
- @Override
- public void firePropertyChangeEvent(String name, Object oldValue, Object newValue) {
- PropertyChangeEvent event = new PropertyChangeEvent(this, name, oldValue, newValue);
- Object[] listeners = fListeners.getListeners();
- for (int i = 0; i < listeners.length; i++) {
- ((IPropertyChangeListener) listeners[i]).propertyChange(event);
- }
- }
+ fProgressMonitor = progressMonitor;
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean getBoolean(String name) {
- return getNode().getBoolean(name, BOOLEAN_DEFAULT_DEFAULT);
- }
+ if (isCanceled()) {
+ return Status.CANCEL_STATUS;
+ }
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean getDefaultBoolean(String name) {
- return BOOLEAN_DEFAULT_DEFAULT;
- }
+ ITextViewer textViewer = getViewer();
+ if (textViewer == null) {
+ return Status.CANCEL_STATUS;
+ }
- /**
- * {@inheritDoc}
- */
- @Override
- public double getDefaultDouble(String name) {
- return DOUBLE_DEFAULT_DEFAULT;
- }
+ IDocument document = textViewer.getDocument();
+ if (document == null) {
+ return Status.CANCEL_STATUS;
+ }
- /**
- * {@inheritDoc}
- */
- @Override
- public float getDefaultFloat(String name) {
- return FLOAT_DEFAULT_DEFAULT;
- }
+ IDocumentProvider documentProvider = getDocumentProvider();
+ if (documentProvider == null) {
+ return Status.CANCEL_STATUS;
+ }
- /**
- * {@inheritDoc}
- */
- @Override
- public int getDefaultInt(String name) {
- return INT_DEFAULT_DEFAULT;
- }
+ IAnnotationModel annotationModel = documentProvider.getAnnotationModel(getEditorInput());
+ if (annotationModel == null) {
+ return Status.CANCEL_STATUS;
+ }
- /**
- * {@inheritDoc}
- */
- @Override
- public long getDefaultLong(String name) {
- return LONG_DEFAULT_DEFAULT;
- }
+ // Add occurrence annotations
+ int length = fPositions.length;
+ Map<Annotation, Position> annotationMap = new HashMap<Annotation, Position>(length);
+ for (int i = 0; i < length; i++) {
- /**
- * {@inheritDoc}
- */
- @Override
- public String getDefaultString(String name) {
- return STRING_DEFAULT_DEFAULT;
- }
+ if (isCanceled()) {
+ return Status.CANCEL_STATUS;
+ }
- /**
- * {@inheritDoc}
- */
- @Override
- public double getDouble(String name) {
- return getNode().getDouble(name, DOUBLE_DEFAULT_DEFAULT);
- }
+ String message;
+ Position position = fPositions[i];
- /**
- * {@inheritDoc}
- */
- @Override
- public float getFloat(String name) {
- return getNode().getFloat(name, FLOAT_DEFAULT_DEFAULT);
- }
+ // Create & add annotation
+ try {
+ message = document.get(position.offset, position.length);
+ } catch (BadLocationException ex) {
+ // Skip this match
+ continue;
+ }
+ annotationMap.put(new Annotation("com.google.dart.tools.ui.occurrences", false, message), //$NON-NLS-1$
+ position);
+ }
- /**
- * {@inheritDoc}
- */
- @Override
- public int getInt(String name) {
- return getNode().getInt(name, INT_DEFAULT_DEFAULT);
- }
+ if (isCanceled()) {
+ return Status.CANCEL_STATUS;
+ }
- /**
- * {@inheritDoc}
- */
- @Override
- public long getLong(String name) {
- return getNode().getLong(name, LONG_DEFAULT_DEFAULT);
+ synchronized (getLockObject(annotationModel)) {
+ if (annotationModel instanceof IAnnotationModelExtension) {
+ ((IAnnotationModelExtension) annotationModel).replaceAnnotations(
+ fOccurrenceAnnotations,
+ annotationMap);
+ } else {
+ removeOccurrenceAnnotations();
+ Iterator<Map.Entry<Annotation, Position>> iter = annotationMap.entrySet().iterator();
+ while (iter.hasNext()) {
+ Map.Entry<Annotation, Position> mapEntry = iter.next();
+ annotationModel.addAnnotation(mapEntry.getKey(), mapEntry.getValue());
+ }
+ }
+ fOccurrenceAnnotations = annotationMap.keySet().toArray(
+ new Annotation[annotationMap.keySet().size()]);
+ }
+
+ return Status.OK_STATUS;
}
- /**
- * {@inheritDoc}
- */
- @Override
- public String getString(String name) {
- return getNode().get(name, STRING_DEFAULT_DEFAULT);
+ // cannot use cancel() because it is declared final
+ void doCancel() {
+ fCanceled = true;
+ cancel();
}
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean isDefault(String name) {
- return false;
+ private boolean isCanceled() {
+ return fCanceled
+ || fProgressMonitor.isCanceled()
+ || fPostSelectionValidator != null
+ && !(fPostSelectionValidator.isValid(fSelection) || fForcedMarkOccurrencesSelection == fSelection)
+ || LinkedModeModel.hasInstalledModel(fDocument);
}
+ }
- /**
- * {@inheritDoc}
+ /**
+ * Cancels the occurrences finder job upon document changes.
+ */
+ class OccurrencesFinderJobCanceler implements IDocumentListener, ITextInputListener {
+
+ /*
+ * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org
+ * .eclipse.jface.text.DocumentEvent)
*/
@Override
- public boolean needsSaving() {
- try {
- return getNode().keys().length > 0;
- } catch (BackingStoreException e) {
- // ignore
+ public void documentAboutToBeChanged(DocumentEvent event) {
+ if (fOccurrencesFinderJob != null) {
+ fOccurrencesFinderJob.doCancel();
}
- return true;
}
- /**
- * {@inheritDoc}
+ /*
+ * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.
+ * jface.text.DocumentEvent)
*/
@Override
- public void putValue(String name, String value) {
- throw new UnsupportedOperationException();
+ public void documentChanged(DocumentEvent event) {
}
- /**
- * {@inheritDoc}
+ /*
+ * @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged
+ * (org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument)
*/
@Override
- public void removePropertyChangeListener(IPropertyChangeListener listener) {
- fListeners.remove(listener);
- if (fListeners.size() == 0) {
- getNode().removePreferenceChangeListener(fListener);
+ public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
+ if (oldInput == null) {
+ return;
}
+
+ oldInput.removeDocumentListener(this);
}
- /**
- * {@inheritDoc}
+ /*
+ * @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse
+ * .jface.text.IDocument, org.eclipse.jface.text.IDocument)
*/
@Override
- public void setDefault(String name, boolean value) {
- throw new UnsupportedOperationException();
+ public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
+ if (newInput == null) {
+ return;
+ }
+ newInput.addDocumentListener(this);
}
- /**
- * {@inheritDoc}
- */
- @Override
- public void setDefault(String name, double value) {
- throw new UnsupportedOperationException();
+ public void install() {
+ ISourceViewer sourceViewer = getSourceViewer();
+ if (sourceViewer == null) {
+ return;
+ }
+
+ StyledText text = sourceViewer.getTextWidget();
+ if (text == null || text.isDisposed()) {
+ return;
+ }
+
+ sourceViewer.addTextInputListener(this);
+
+ IDocument document = sourceViewer.getDocument();
+ if (document != null) {
+ document.addDocumentListener(this);
+ }
}
- /**
- * {@inheritDoc}
- */
- @Override
- public void setDefault(String name, float value) {
- throw new UnsupportedOperationException();
+ public void uninstall() {
+ ISourceViewer sourceViewer = getSourceViewer();
+ if (sourceViewer != null) {
+ sourceViewer.removeTextInputListener(this);
+ }
+
+ IDocumentProvider documentProvider = getDocumentProvider();
+ if (documentProvider != null) {
+ IDocument document = documentProvider.getDocument(getEditorInput());
+ if (document != null) {
+ document.removeDocumentListener(this);
+ }
+ }
}
+ }
- /**
- * {@inheritDoc}
+ /**
+ * Internal activation listener.
+ */
+ private class ActivationListener implements IWindowListener {
+
+ /*
+ * @see org.eclipse.ui.IWindowListener#windowActivated(org.eclipse.ui. IWorkbenchWindow)
*/
@Override
- public void setDefault(String name, int value) {
- throw new UnsupportedOperationException();
+ public void windowActivated(IWorkbenchWindow window) {
+ if (window == getEditorSite().getWorkbenchWindow() && fMarkOccurrenceAnnotations
+ && isActivePart()) {
+ fForcedMarkOccurrencesSelection = getSelectionProvider().getSelection();
+ try {
+ DartElement input = getInputDartElement();
+ if (input != null) {
+ updateOccurrenceAnnotations(
+ (ITextSelection) fForcedMarkOccurrencesSelection,
+ DartToolsPlugin.getDefault().getASTProvider().getAST(
+ input,
+ ASTProvider.WAIT_NO,
+ getProgressMonitor()));
+ }
+ } catch (Exception ex) {
+ // ignore it
+ }
+ }
}
- /**
- * {@inheritDoc}
+ /*
+ * @see org.eclipse.ui.IWindowListener#windowClosed(org.eclipse.ui.IWorkbenchWindow )
*/
@Override
- public void setDefault(String name, long value) {
- throw new UnsupportedOperationException();
+ public void windowClosed(IWorkbenchWindow window) {
}
- /**
- * {@inheritDoc}
+ /*
+ * @see org.eclipse.ui.IWindowListener#windowDeactivated(org.eclipse.ui. IWorkbenchWindow)
*/
@Override
- public void setDefault(String name, String defaultObject) {
- throw new UnsupportedOperationException();
+ public void windowDeactivated(IWorkbenchWindow window) {
+ if (window == getEditorSite().getWorkbenchWindow() && fMarkOccurrenceAnnotations
+ && isActivePart()) {
+ removeOccurrenceAnnotations();
+ }
}
- /**
- * {@inheritDoc}
+ /*
+ * @see org.eclipse.ui.IWindowListener#windowOpened(org.eclipse.ui.IWorkbenchWindow )
*/
@Override
- public void setToDefault(String name) {
- throw new UnsupportedOperationException();
+ public void windowOpened(IWorkbenchWindow window) {
}
+ }
+ /**
+ * Instances of the class <code>ASTCache</code> maintain an AST structure corresponding to the
+ * contents of an editor's document.
+ */
+ private static class ASTCache {
/**
- * {@inheritDoc}
+ * The time at which the cache was last cleared.
*/
- @Override
- public void setValue(String name, boolean value) {
- throw new UnsupportedOperationException();
- }
+ private long clearTime;
/**
- * {@inheritDoc}
+ * The AST corresponding to the contents of the editor's document, or <code>null</code> if the
+ * AST structure has not been accessed since the last time the cache was cleared.
*/
- @Override
- public void setValue(String name, double value) {
- throw new UnsupportedOperationException();
- }
+ private SoftReference<DartUnit> cachedAST;
/**
- * {@inheritDoc}
+ * Initialize a newly created class to be empty.
*/
- @Override
- public void setValue(String name, float value) {
- throw new UnsupportedOperationException();
+ public ASTCache() {
+ clearTime = 0L;
+ cachedAST = null;
}
/**
- * {@inheritDoc}
+ * Clear the contents of this cache.
*/
- @Override
- public void setValue(String name, int value) {
- throw new UnsupportedOperationException();
+ public void clear() {
+ synchronized (this) {
+ clearTime = System.nanoTime();
+ cachedAST = null;
+ }
}
/**
- * {@inheritDoc}
+ * Return the AST structure held in this cache, or <code>null</code> if the AST structure needs
+ * to be created.
+ *
+ * @return the AST structure held in this cache
*/
- @Override
- public void setValue(String name, long value) {
- throw new UnsupportedOperationException();
+ public DartUnit getAST() {
+ synchronized (this) {
+ if (cachedAST != null) {
+ return cachedAST.get();
+ }
+ }
+ return null;
}
/**
- * {@inheritDoc}
+ * Set the AST structure held in this cache to the given AST structure provided that the cache
+ * has not been cleared since the time at which the AST structure was created.
+ *
+ * @param creationTime the time at which the AST structure was created (in nanoseconds)
+ * @param ast the AST structure that is to be cached
*/
- @Override
- public void setValue(String name, String value) {
- throw new UnsupportedOperationException();
- }
-
- private IEclipsePreferences getNode() {
- return fContext.getNode(fQualifier);
+ public void setAST(long creationTime, DartUnit ast) {
+ synchronized (this) {
+ if (creationTime > clearTime) {
+ cachedAST = new SoftReference<DartUnit>(ast);
+ }
+ }
}
-
}
/**
@@ -2255,6 +2256,12 @@ public abstract class DartEditor extends AbstractDecoratedTextEditor implements
}
}
+ public void setPreferences(IPreferenceStore store) {
+ uninstallSemanticHighlighting();
+ super.setPreferenceStore(store);
+ installSemanticHighlighting();
+ }
+
public void setSelection(DartElement element) {
if (element == null || element instanceof CompilationUnit) {
@@ -3427,8 +3434,12 @@ public abstract class DartEditor extends AbstractDecoratedTextEditor implements
@Override
protected void performSave(boolean overwrite, IProgressMonitor progressMonitor) {
+ Timer timer = new Timer("save");
+
performSaveActions();
super.performSave(overwrite, progressMonitor);
+
+ timer.stop();
}
@Override

Powered by Google App Engine
This is Rietveld 408576698