| /******************************************************************************* |
| * Copyright (c) 2001, 2010 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Jens Lukowski/Innoopract - initial renaming/restructuring |
| * |
| *******************************************************************************/ |
| package org.eclipse.wst.sse.ui; |
| |
| import java.io.IOException; |
| import java.lang.reflect.Method; |
| import java.text.MessageFormat; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.LinkedHashSet; |
| import java.util.List; |
| import java.util.ResourceBundle; |
| import java.util.Set; |
| import java.util.Timer; |
| import java.util.TimerTask; |
| |
| import org.eclipse.core.commands.AbstractHandler; |
| import org.eclipse.core.commands.ExecutionEvent; |
| import org.eclipse.core.commands.ExecutionException; |
| import org.eclipse.core.commands.IHandler; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IConfigurationElement; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.ISafeRunnable; |
| import org.eclipse.core.runtime.ListenerList; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.SafeRunner; |
| import org.eclipse.core.runtime.content.IContentType; |
| import org.eclipse.core.runtime.content.IContentTypeManager; |
| import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget; |
| import org.eclipse.emf.common.command.Command; |
| import org.eclipse.jface.action.Action; |
| import org.eclipse.jface.action.IAction; |
| import org.eclipse.jface.action.IMenuManager; |
| import org.eclipse.jface.action.IStatusLineManager; |
| import org.eclipse.jface.action.MenuManager; |
| import org.eclipse.jface.action.Separator; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.preference.PreferenceConverter; |
| import org.eclipse.jface.text.AbstractInformationControlManager; |
| import org.eclipse.jface.text.BadLocationException; |
| import org.eclipse.jface.text.DefaultInformationControl; |
| import org.eclipse.jface.text.IBlockTextSelection; |
| import org.eclipse.jface.text.IDocument; |
| import org.eclipse.jface.text.IInformationControl; |
| import org.eclipse.jface.text.IInformationControlCreator; |
| import org.eclipse.jface.text.IRegion; |
| import org.eclipse.jface.text.ISelectionValidator; |
| import org.eclipse.jface.text.ITextHover; |
| import org.eclipse.jface.text.ITextOperationTarget; |
| import org.eclipse.jface.text.ITextSelection; |
| import org.eclipse.jface.text.ITextViewer; |
| import org.eclipse.jface.text.ITextViewerExtension; |
| import org.eclipse.jface.text.ITextViewerExtension2; |
| import org.eclipse.jface.text.ITextViewerExtension5; |
| import org.eclipse.jface.text.ITypedRegion; |
| import org.eclipse.jface.text.Region; |
| import org.eclipse.jface.text.TextSelection; |
| import org.eclipse.jface.text.contentassist.ContentAssistant; |
| import org.eclipse.jface.text.contentassist.IContentAssistant; |
| import org.eclipse.jface.text.information.IInformationPresenter; |
| import org.eclipse.jface.text.information.IInformationProvider; |
| import org.eclipse.jface.text.information.InformationPresenter; |
| import org.eclipse.jface.text.reconciler.DirtyRegion; |
| import org.eclipse.jface.text.reconciler.IReconciler; |
| import org.eclipse.jface.text.source.Annotation; |
| import org.eclipse.jface.text.source.DefaultCharacterPairMatcher; |
| import org.eclipse.jface.text.source.ICharacterPairMatcher; |
| import org.eclipse.jface.text.source.ISourceViewer; |
| import org.eclipse.jface.text.source.IVerticalRuler; |
| import org.eclipse.jface.text.source.LineChangeHover; |
| import org.eclipse.jface.text.source.SourceViewerConfiguration; |
| import org.eclipse.jface.text.source.projection.ProjectionSupport; |
| import org.eclipse.jface.text.source.projection.ProjectionViewer; |
| import org.eclipse.jface.util.PropertyChangeEvent; |
| import org.eclipse.jface.util.SafeRunnable; |
| import org.eclipse.jface.viewers.DoubleClickEvent; |
| import org.eclipse.jface.viewers.IDoubleClickListener; |
| import org.eclipse.jface.viewers.ILabelProvider; |
| import org.eclipse.jface.viewers.IPostSelectionProvider; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.ISelectionChangedListener; |
| import org.eclipse.jface.viewers.ISelectionProvider; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.SelectionChangedEvent; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.custom.StyledText; |
| import org.eclipse.swt.custom.VerifyKeyListener; |
| import org.eclipse.swt.dnd.DND; |
| import org.eclipse.swt.dnd.DropTarget; |
| import org.eclipse.swt.events.VerifyEvent; |
| import org.eclipse.swt.graphics.Color; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.graphics.RGB; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Menu; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.IEditorActionBarContributor; |
| import org.eclipse.ui.IEditorInput; |
| import org.eclipse.ui.IEditorPart; |
| import org.eclipse.ui.IEditorSite; |
| import org.eclipse.ui.IFileEditorInput; |
| import org.eclipse.ui.IPageLayout; |
| import org.eclipse.ui.IPartListener; |
| import org.eclipse.ui.ISharedImages; |
| import org.eclipse.ui.IStorageEditorInput; |
| import org.eclipse.ui.IWorkbenchActionConstants; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.PartInitException; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.contexts.IContextService; |
| import org.eclipse.ui.editors.text.EditorsUI; |
| import org.eclipse.ui.editors.text.ITextEditorHelpContextIds; |
| import org.eclipse.ui.editors.text.TextEditor; |
| import org.eclipse.ui.handlers.IHandlerService; |
| import org.eclipse.ui.help.IWorkbenchHelpSystem; |
| import org.eclipse.ui.part.IShowInTargetList; |
| import org.eclipse.ui.progress.IWorkbenchSiteProgressService; |
| import org.eclipse.ui.texteditor.ChainedPreferenceStore; |
| import org.eclipse.ui.texteditor.DefaultRangeIndicator; |
| import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds; |
| import org.eclipse.ui.texteditor.IDocumentProvider; |
| import org.eclipse.ui.texteditor.IStatusField; |
| import org.eclipse.ui.texteditor.ITextEditor; |
| import org.eclipse.ui.texteditor.ITextEditorActionConstants; |
| import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds; |
| import org.eclipse.ui.texteditor.ITextEditorExtension; |
| import org.eclipse.ui.texteditor.ITextEditorExtension2; |
| import org.eclipse.ui.texteditor.ITextEditorExtension3; |
| import org.eclipse.ui.texteditor.ITextEditorExtension4; |
| import org.eclipse.ui.texteditor.ITextEditorExtension5; |
| import org.eclipse.ui.texteditor.IUpdate; |
| import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds; |
| import org.eclipse.ui.texteditor.SourceViewerDecorationSupport; |
| import org.eclipse.ui.texteditor.TextOperationAction; |
| import org.eclipse.ui.views.contentoutline.IContentOutlinePage; |
| import org.eclipse.ui.views.properties.IPropertySheetPage; |
| import org.eclipse.wst.sse.core.StructuredModelManager; |
| import org.eclipse.wst.sse.core.internal.document.IDocumentCharsetDetector; |
| import org.eclipse.wst.sse.core.internal.encoding.EncodingMemento; |
| import org.eclipse.wst.sse.core.internal.provisional.IModelStateListener; |
| import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel; |
| import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion; |
| import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument; |
| import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion; |
| import org.eclipse.wst.sse.core.internal.text.IExecutionDelegatable; |
| import org.eclipse.wst.sse.core.internal.undo.IStructuredTextUndoManager; |
| import org.eclipse.wst.sse.core.utils.StringUtils; |
| import org.eclipse.wst.sse.ui.internal.ExtendedConfigurationBuilder; |
| import org.eclipse.wst.sse.ui.internal.ExtendedEditorActionBuilder; |
| import org.eclipse.wst.sse.ui.internal.ExtendedEditorDropTargetAdapter; |
| import org.eclipse.wst.sse.ui.internal.IExtendedContributor; |
| import org.eclipse.wst.sse.ui.internal.IModelProvider; |
| import org.eclipse.wst.sse.ui.internal.IPopupMenuContributor; |
| import org.eclipse.wst.sse.ui.internal.IStructuredTextEditorActionConstants; |
| import org.eclipse.wst.sse.ui.internal.Logger; |
| import org.eclipse.wst.sse.ui.internal.ReadOnlyAwareDropTargetAdapter; |
| import org.eclipse.wst.sse.ui.internal.SSEUIMessages; |
| import org.eclipse.wst.sse.ui.internal.SSEUIPlugin; |
| import org.eclipse.wst.sse.ui.internal.StorageModelProvider; |
| import org.eclipse.wst.sse.ui.internal.StructuredTextViewer; |
| import org.eclipse.wst.sse.ui.internal.UnknownContentTypeDialog; |
| import org.eclipse.wst.sse.ui.internal.actions.ActionDefinitionIds; |
| import org.eclipse.wst.sse.ui.internal.actions.StructuredTextEditorActionConstants; |
| import org.eclipse.wst.sse.ui.internal.contentoutline.ConfigurableContentOutlinePage; |
| import org.eclipse.wst.sse.ui.internal.debug.BreakpointRulerAction; |
| import org.eclipse.wst.sse.ui.internal.debug.EditBreakpointAction; |
| import org.eclipse.wst.sse.ui.internal.debug.ManageBreakpointAction; |
| import org.eclipse.wst.sse.ui.internal.debug.ToggleBreakpointAction; |
| import org.eclipse.wst.sse.ui.internal.debug.ToggleBreakpointsTarget; |
| import org.eclipse.wst.sse.ui.internal.derived.HTMLTextPresenter; |
| import org.eclipse.wst.sse.ui.internal.editor.EditorModelUtil; |
| import org.eclipse.wst.sse.ui.internal.editor.IHelpContextIds; |
| import org.eclipse.wst.sse.ui.internal.editor.SelectionConvertor; |
| import org.eclipse.wst.sse.ui.internal.editor.StructuredModelDocumentProvider; |
| import org.eclipse.wst.sse.ui.internal.extension.BreakpointProviderBuilder; |
| import org.eclipse.wst.sse.ui.internal.hyperlink.OpenHyperlinkAction; |
| import org.eclipse.wst.sse.ui.internal.preferences.EditorPreferenceNames; |
| import org.eclipse.wst.sse.ui.internal.projection.AbstractStructuredFoldingStrategy; |
| import org.eclipse.wst.sse.ui.internal.properties.ConfigurablePropertySheetPage; |
| import org.eclipse.wst.sse.ui.internal.properties.ShowPropertiesAction; |
| import org.eclipse.wst.sse.ui.internal.provisional.extensions.ConfigurationPointCalculator; |
| import org.eclipse.wst.sse.ui.internal.provisional.extensions.ISourceEditingTextTools; |
| import org.eclipse.wst.sse.ui.internal.provisional.extensions.breakpoint.NullSourceEditingTextTools; |
| import org.eclipse.wst.sse.ui.internal.provisional.preferences.CommonEditorPreferenceNames; |
| import org.eclipse.wst.sse.ui.internal.quickoutline.QuickOutlineHandler; |
| import org.eclipse.wst.sse.ui.internal.quickoutline.QuickOutlinePopupDialog; |
| import org.eclipse.wst.sse.ui.internal.reconcile.DirtyRegionProcessor; |
| import org.eclipse.wst.sse.ui.internal.reconcile.DocumentRegionProcessor; |
| import org.eclipse.wst.sse.ui.internal.selection.SelectionHistory; |
| import org.eclipse.wst.sse.ui.internal.style.SemanticHighlightingManager; |
| import org.eclipse.wst.sse.ui.internal.text.DocumentRegionEdgeMatcher; |
| import org.eclipse.wst.sse.ui.internal.text.SourceInfoProvider; |
| import org.eclipse.wst.sse.ui.internal.util.Assert; |
| import org.eclipse.wst.sse.ui.internal.util.EditorUtility; |
| import org.eclipse.wst.sse.ui.quickoutline.AbstractQuickOutlineConfiguration; |
| import org.eclipse.wst.sse.ui.reconcile.ISourceReconcilingListener; |
| import org.eclipse.wst.sse.ui.typing.AbstractCharacterPairInserter; |
| import org.eclipse.wst.sse.ui.views.contentoutline.ContentOutlineConfiguration; |
| import org.eclipse.wst.sse.ui.views.properties.PropertySheetConfiguration; |
| |
| /** |
| * A Text Editor for editing structured models and structured documents. |
| * <p> |
| * This class is not meant to be subclassed.<br /> |
| * New content types may associate source viewer, content outline, and |
| * property sheet configurations to extend the existing functionality. |
| * </p> |
| * |
| * @see org.eclipse.wst.sse.ui.StructuredTextViewerConfiguration |
| * @see org.eclipse.wst.sse.ui.views.contentoutline.ContentOutlineConfiguration |
| * @see org.eclipse.wst.sse.ui.views.properties.PropertySheetConfiguration |
| * |
| * @since 1.0 |
| */ |
| |
| public class StructuredTextEditor extends TextEditor { |
| private class GotoMatchingBracketHandler extends AbstractHandler { |
| public Object execute(ExecutionEvent arg0) throws ExecutionException { |
| gotoMatchingBracket(); |
| return null; |
| } |
| } |
| |
| private class InternalModelStateListener implements IModelStateListener { |
| public void modelAboutToBeChanged(IStructuredModel model) { |
| if (getTextViewer() != null) { |
| // getTextViewer().setRedraw(false); |
| } |
| } |
| |
| public void modelAboutToBeReinitialized(IStructuredModel structuredModel) { |
| if (getTextViewer() != null) { |
| // getTextViewer().setRedraw(false); |
| getTextViewer().unconfigure(); |
| setStatusLineMessage(null); |
| } |
| } |
| |
| public void modelChanged(IStructuredModel model) { |
| if (getSourceViewer() != null) { |
| // getTextViewer().setRedraw(true); |
| // Since the model can be changed on a background |
| // thread, we will update menus on display thread, |
| // if we are not already on display thread, |
| // and if there is not an update already pending. |
| // (we can get lots of 'modelChanged' events in rapid |
| // succession, so only need to do one. |
| if (!fUpdateMenuTextPending) { |
| runOnDisplayThreadIfNeededed(new Runnable() { |
| public void run() { |
| updateMenuText(); |
| fUpdateMenuTextPending = false; |
| } |
| }); |
| } |
| |
| } |
| } |
| |
| public void modelDirtyStateChanged(IStructuredModel model, boolean isDirty) { |
| // do nothing |
| } |
| |
| public void modelReinitialized(IStructuredModel structuredModel) { |
| try { |
| if (getSourceViewer() != null) { |
| SourceViewerConfiguration cfg = getSourceViewerConfiguration(); |
| getSourceViewer().configure(cfg); |
| } |
| } |
| catch (Exception e) { |
| // https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=1166 |
| // investigate each error case post beta |
| Logger.logException("problem trying to configure after model change", e); //$NON-NLS-1$ |
| } |
| finally { |
| // so we don't freeze workbench (eg. during page language or |
| // content type change) |
| ((ITextViewerExtension) getSourceViewer()).setRedraw(true); |
| |
| IWorkbenchSiteProgressService service = (IWorkbenchSiteProgressService) getSite().getService(IWorkbenchSiteProgressService.class); |
| if (service != null) { |
| service.warnOfContentChange(); |
| } |
| } |
| } |
| |
| // Note: this one should probably be used to |
| // control viewer |
| // instead of viewer having its own listener |
| public void modelResourceDeleted(IStructuredModel model) { |
| // do nothing |
| } |
| |
| public void modelResourceMoved(IStructuredModel originalmodel, IStructuredModel movedmodel) { |
| // do nothing |
| } |
| |
| /** |
| * This 'Runnable' should be very brief, and should not "call out" to |
| * other code especially if it depends on the state of the model. |
| * |
| * @param r |
| */ |
| private void runOnDisplayThreadIfNeededed(Runnable r) { |
| // if there is no Display at all (that is, running headless), |
| // or if we are already running on the display thread, then |
| // simply execute the runnable. |
| if (getDisplay() == null || (Thread.currentThread() == getDisplay().getThread())) { |
| r.run(); |
| } |
| else { |
| // otherwise force the runnable to run on the display thread. |
| getDisplay().asyncExec(r); |
| } |
| } |
| } |
| |
| /** |
| * Listens to double-click and selection from the outline page |
| */ |
| private class OutlinePageListener implements IDoubleClickListener, ISelectionChangedListener { |
| public void doubleClick(DoubleClickEvent event) { |
| if (event.getSelection().isEmpty()) |
| return; |
| |
| int start = -1; |
| int length = 0; |
| if (event.getSelection() instanceof IStructuredSelection) { |
| ISelection currentSelection = getSelectionProvider().getSelection(); |
| if (currentSelection instanceof IStructuredSelection) { |
| Object current = ((IStructuredSelection) currentSelection).toArray(); |
| Object newSelection = ((IStructuredSelection) event.getSelection()).toArray(); |
| if (!current.equals(newSelection)) { |
| IStructuredSelection selection = (IStructuredSelection) event.getSelection(); |
| Object o = selection.getFirstElement(); |
| if (o instanceof IndexedRegion) { |
| start = ((IndexedRegion) o).getStartOffset(); |
| length = ((IndexedRegion) o).getEndOffset() - start; |
| } |
| else if (o instanceof ITextRegion) { |
| start = ((ITextRegion) o).getStart(); |
| length = ((ITextRegion) o).getEnd() - start; |
| } |
| else if (o instanceof IRegion) { |
| start = ((ITextRegion) o).getStart(); |
| length = ((ITextRegion) o).getLength(); |
| } |
| } |
| } |
| } |
| else if (event.getSelection() instanceof ITextSelection) { |
| start = ((ITextSelection) event.getSelection()).getOffset(); |
| length = ((ITextSelection) event.getSelection()).getLength(); |
| } |
| if (start > -1) { |
| getSourceViewer().setRangeIndication(start, length, false); |
| selectAndReveal(start, length); |
| } |
| } |
| |
| public void selectionChanged(SelectionChangedEvent event) { |
| /* |
| * Do not allow selection from other parts to affect selection in |
| * the text widget if it has focus, or if we're still firing a |
| * change of selection. Selection events "bouncing" off of other |
| * parts are all that we can receive if we have focus (since we |
| * forwarded our selection to the service just a moment ago), and |
| * only the user should affect selection if we have focus. |
| */ |
| |
| /* The isFiringSelection check only works if a selection listener */ |
| if (event.getSelection().isEmpty() || fStructuredSelectionProvider.isFiringSelection()) |
| return; |
| |
| if (getSourceViewer() != null && getSourceViewer().getTextWidget() != null && !getSourceViewer().getTextWidget().isDisposed() && !getSourceViewer().getTextWidget().isFocusControl()) { |
| int start = -1; |
| int length = 0; |
| if (event.getSelection() instanceof IStructuredSelection) { |
| ISelection current = getSelectionProvider().getSelection(); |
| if (current instanceof IStructuredSelection) { |
| Object[] currentSelection = ((IStructuredSelection) current).toArray(); |
| Object[] newSelection = ((IStructuredSelection) event.getSelection()).toArray(); |
| if (!Arrays.equals(currentSelection, newSelection)) { |
| if (newSelection.length > 0) { |
| /* |
| * No ordering is guaranteed for multiple |
| * selection |
| */ |
| Object o = newSelection[0]; |
| if (o instanceof IndexedRegion) { |
| start = ((IndexedRegion) o).getStartOffset(); |
| int end = ((IndexedRegion) o).getEndOffset(); |
| if (newSelection.length > 1) { |
| for (int i = 1; i < newSelection.length; i++) { |
| start = Math.min(start, ((IndexedRegion) newSelection[i]).getStartOffset()); |
| end = Math.max(end, ((IndexedRegion) newSelection[i]).getEndOffset()); |
| } |
| length = end - start; |
| } |
| } |
| else if (o instanceof ITextRegion) { |
| start = ((ITextRegion) o).getStart(); |
| int end = ((ITextRegion) o).getEnd(); |
| if (newSelection.length > 1) { |
| for (int i = 1; i < newSelection.length; i++) { |
| start = Math.min(start, ((ITextRegion) newSelection[i]).getStart()); |
| end = Math.max(end, ((ITextRegion) newSelection[i]).getEnd()); |
| } |
| length = end - start; |
| } |
| } |
| else if (o instanceof IRegion) { |
| start = ((IRegion) o).getOffset(); |
| int end = start + ((IRegion) o).getLength(); |
| if (newSelection.length > 1) { |
| for (int i = 1; i < newSelection.length; i++) { |
| start = Math.min(start, ((IRegion) newSelection[i]).getOffset()); |
| end = Math.max(end, ((IRegion) newSelection[i]).getOffset() + ((IRegion) newSelection[i]).getLength()); |
| } |
| length = end - start; |
| } |
| } |
| } |
| } |
| } |
| } |
| else if (event.getSelection() instanceof ITextSelection) { |
| start = ((ITextSelection) event.getSelection()).getOffset(); |
| } |
| if (start > -1) { |
| updateRangeIndication(event.getSelection()); |
| selectAndReveal(start, length); |
| } |
| } |
| } |
| } |
| |
| private class ShowInTargetListAdapter implements IShowInTargetList { |
| /** |
| * Array of ID Strings that define the default show in targets for |
| * this editor. |
| * |
| * @see org.eclipse.ui.part.IShowInTargetList#getShowInTargetIds() |
| * @return the array of ID Strings that define the default show in |
| * targets for this editor. |
| */ |
| public String[] getShowInTargetIds() { |
| return fShowInTargetIds; |
| } |
| } |
| |
| /** |
| * A post selection provider that wraps the provider implemented in |
| * AbstractTextEditor to provide a StructuredTextSelection to post |
| * selection listeners. Listens to selection changes from the source |
| * viewer. |
| */ |
| private static class StructuredSelectionProvider implements IPostSelectionProvider, ISelectionValidator { |
| /** |
| * A "hybrid" text and structured selection class containing the text |
| * selection and a list of selected model objects. The determination |
| * of which model objects matches the text selection is responsibility |
| * of the StructuredSelectionProvider which created this selection |
| * object. |
| */ |
| private static class StructuredTextSelection extends TextSelection implements IStructuredSelection { |
| private Object[] selectedStructured; |
| |
| StructuredTextSelection(IDocument document, int offset, int length, Object[] selectedObjects) { |
| super(document, offset, length); |
| selectedStructured = selectedObjects; |
| } |
| |
| StructuredTextSelection(IDocument document, ITextSelection selection, Object[] selectedObjects) { |
| this(document, selection.getOffset(), selection.getLength(), selectedObjects); |
| } |
| |
| public Object getFirstElement() { |
| Object[] selectedStructures = getSelectedStructures(); |
| return selectedStructures.length > 0 ? selectedStructures[0] : null; |
| } |
| |
| private Object[] getSelectedStructures() { |
| return (selectedStructured != null) ? selectedStructured : new Object[0]; |
| } |
| |
| public boolean isEmpty() { |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=191327 |
| return super.isEmpty() || getSelectedStructures().length == 0; |
| } |
| |
| public Iterator iterator() { |
| return toList().iterator(); |
| } |
| |
| public int size() { |
| return (selectedStructured != null) ? selectedStructured.length : 0; |
| } |
| |
| public Object[] toArray() { |
| return getSelectedStructures(); |
| } |
| |
| public List toList() { |
| return Arrays.asList(getSelectedStructures()); |
| } |
| |
| public String toString() { |
| return getOffset() + ":" + getLength() + "@" + getSelectedStructures(); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| |
| private ISelectionProvider fParentProvider = null; |
| private boolean isFiringSelection = false; |
| private ListenerList listeners = new ListenerList(); |
| private ListenerList postListeners = new ListenerList(); |
| private ISelection fLastSelection = null; |
| private ISelectionProvider fLastSelectionProvider = null; |
| private SelectionChangedEvent fLastUpdatedSelectionChangedEvent = null; |
| private StructuredTextEditor fEditor; |
| /* |
| * Responsible for finding the selected objects within a text |
| * selection. Set/reset by the StructuredTextEditor based on a |
| * per-model adapter on input. |
| */ |
| SelectionConvertor selectionConvertor = new SelectionConvertor(); |
| |
| StructuredSelectionProvider(ISelectionProvider parentProvider, StructuredTextEditor structuredTextEditor) { |
| fParentProvider = parentProvider; |
| fEditor = structuredTextEditor; |
| fParentProvider.addSelectionChangedListener(new ISelectionChangedListener() { |
| public void selectionChanged(SelectionChangedEvent event) { |
| handleSelectionChanged(event); |
| } |
| }); |
| if (fParentProvider instanceof IPostSelectionProvider) { |
| ((IPostSelectionProvider) fParentProvider).addPostSelectionChangedListener(new ISelectionChangedListener() { |
| public void selectionChanged(SelectionChangedEvent event) { |
| handlePostSelectionChanged(event); |
| } |
| }); |
| } |
| } |
| |
| public void addPostSelectionChangedListener(ISelectionChangedListener listener) { |
| postListeners.add(listener); |
| } |
| |
| public void addSelectionChangedListener(ISelectionChangedListener listener) { |
| listeners.add(listener); |
| } |
| |
| public void dispose() { |
| fEditor = null; |
| listeners.clear(); |
| postListeners.clear(); |
| selectionConvertor = null; |
| } |
| |
| private void fireSelectionChanged(final SelectionChangedEvent event, ListenerList listenerList) { |
| Object[] listeners = listenerList.getListeners(); |
| isFiringSelection = true; |
| for (int i = 0; i < listeners.length; ++i) { |
| final ISelectionChangedListener l = (ISelectionChangedListener) listeners[i]; |
| SafeRunner.run(new SafeRunnable() { |
| public void run() { |
| l.selectionChanged(event); |
| } |
| }); |
| } |
| isFiringSelection = false; |
| } |
| |
| private ISelectionProvider getParentProvider() { |
| return fParentProvider; |
| } |
| |
| public ISelection getSelection() { |
| fLastSelection = null; |
| fLastSelectionProvider = null; |
| fLastUpdatedSelectionChangedEvent = null; |
| |
| /* |
| * When a client explicitly asks for selection, provide the hybrid |
| * result. |
| */ |
| ISelection selection = getParentProvider().getSelection(); |
| if (!(selection instanceof IStructuredSelection) && selection instanceof ITextSelection) { |
| IStructuredModel structuredModel = null; |
| StructuredTextEditor localEditor = getStructuredTextEditor(); |
| if (localEditor != null) { |
| structuredModel = localEditor.getInternalModel(); |
| if (structuredModel != null) { |
| if (localEditor.isBlockSelectionModeEnabled()) { |
| /* |
| * Block selection handling - find the overlapping |
| * objects on each line, keeping in mind that the |
| * selected block may not overlap actual lines or |
| * columns of the document. |
| * IBlockTextSelection.getRegions() should handle |
| * that for us... |
| */ |
| IBlockTextSelection blockSelection = (IBlockTextSelection) selection; |
| IRegion[] regions = blockSelection.getRegions(); |
| Set blockObjects = new LinkedHashSet(); |
| for (int i = 0; i < regions.length; i++) { |
| Object[] objects = selectionConvertor.getElements(structuredModel, regions[i].getOffset(), regions[i].getLength()); |
| for (int j = 0; j < objects.length; j++) { |
| blockObjects.add(objects[j]); |
| } |
| } |
| selection = new StructuredTextSelection(getDocument(), (ITextSelection) selection, blockObjects.toArray()); |
| } |
| else { |
| int start = ((ITextSelection) selection).getOffset(); |
| int end = start + ((ITextSelection) selection).getLength(); |
| selection = new StructuredTextSelection(getDocument(), (ITextSelection) selection, selectionConvertor.getElements(structuredModel, start, end)); |
| } |
| } |
| } |
| if (selection == null) { |
| selection = new StructuredTextSelection(getDocument(), (ITextSelection) selection, new Object[0]); |
| } |
| } |
| |
| return selection; |
| } |
| |
| private StructuredTextEditor getStructuredTextEditor() { |
| return fEditor; |
| } |
| |
| void handlePostSelectionChanged(SelectionChangedEvent event) { |
| SelectionChangedEvent updatedEvent = null; |
| if (fLastSelection == event.getSelection() && fLastSelectionProvider == event.getSelectionProvider()) { |
| updatedEvent = fLastUpdatedSelectionChangedEvent; |
| } |
| else { |
| updatedEvent = updateEvent(event); |
| } |
| // only update the range indicator on post selection |
| StructuredTextEditor localEditor = fEditor; |
| |
| if (localEditor != null) { |
| localEditor.updateRangeIndication(updatedEvent.getSelection()); |
| fireSelectionChanged(updatedEvent, postListeners); |
| } |
| } |
| |
| void handleSelectionChanged(SelectionChangedEvent event) { |
| SelectionChangedEvent updatedEvent = event; |
| if (fLastSelection != event.getSelection() || fLastSelectionProvider != event.getSelectionProvider()) { |
| fLastSelection = event.getSelection(); |
| fLastSelectionProvider = event.getSelectionProvider(); |
| fLastUpdatedSelectionChangedEvent = updatedEvent = updateEvent(event); |
| } |
| fireSelectionChanged(updatedEvent, listeners); |
| } |
| |
| IDocument getDocument() { |
| return fEditor.getDocumentProvider().getDocument(fEditor.getEditorInput()); |
| } |
| |
| |
| boolean isFiringSelection() { |
| return isFiringSelection; |
| } |
| |
| public boolean isValid(ISelection selection) { |
| // ISSUE: is not clear default behavior should be true? |
| // But not clear is this default would apply for our editor. |
| boolean result = true; |
| // if editor is "gone", can not be valid |
| StructuredTextEditor e = getStructuredTextEditor(); |
| if (e == null || e.fEditorDisposed) { |
| result = false; |
| } |
| // else defer to parent |
| else if (getParentProvider() instanceof ISelectionValidator) { |
| result = ((ISelectionValidator) getParentProvider()).isValid(selection); |
| } |
| return result; |
| } |
| |
| public void removePostSelectionChangedListener(ISelectionChangedListener listener) { |
| postListeners.remove(listener); |
| } |
| |
| public void removeSelectionChangedListener(ISelectionChangedListener listener) { |
| listeners.remove(listener); |
| } |
| |
| public void setSelection(ISelection selection) { |
| if (isFiringSelection()) { |
| return; |
| } |
| |
| fLastSelection = null; |
| fLastSelectionProvider = null; |
| fLastUpdatedSelectionChangedEvent = null; |
| |
| ISelection textSelection = updateSelection(selection); |
| getParentProvider().setSelection(textSelection); |
| StructuredTextEditor localEditor = getStructuredTextEditor(); |
| if (localEditor != null) { |
| localEditor.updateRangeIndication(textSelection); |
| } |
| } |
| |
| /** |
| * Create a corresponding event that contains a |
| * StructuredTextselection |
| * |
| * @param event |
| * @return |
| */ |
| private SelectionChangedEvent updateEvent(SelectionChangedEvent event) { |
| ISelection selection = event.getSelection(); |
| if (selection instanceof ITextSelection && !(selection instanceof IStructuredSelection)) { |
| IStructuredModel structuredModel = null; |
| StructuredTextEditor localEditor = getStructuredTextEditor(); |
| if (localEditor != null) { |
| structuredModel = localEditor.getInternalModel(); |
| if (structuredModel != null) { |
| int start = ((ITextSelection) selection).getOffset(); |
| int end = start + ((ITextSelection) selection).getLength(); |
| selection = new StructuredTextSelection(getDocument(), (ITextSelection) event.getSelection(), selectionConvertor.getElements(structuredModel, start, end)); |
| } |
| } |
| if (selection == null) |
| selection = new StructuredTextSelection(getDocument(), (ITextSelection) event.getSelection(), new Object[0]); |
| } |
| SelectionChangedEvent newEvent = new SelectionChangedEvent(event.getSelectionProvider(), selection); |
| return newEvent; |
| } |
| |
| /** |
| * Create a corresponding StructuredTextselection |
| * |
| * @param selection |
| * @return |
| */ |
| private ISelection updateSelection(ISelection selection) { |
| ISelection updated = selection; |
| if (selection instanceof IStructuredSelection && !(selection instanceof ITextSelection) && !selection.isEmpty()) { |
| Object[] selectedObjects = ((IStructuredSelection) selection).toArray(); |
| if (selectedObjects.length > 0) { |
| int start = -1; |
| int length = 0; |
| |
| // no ordering is guaranteed for multiple selection |
| Object o = selectedObjects[0]; |
| if (o instanceof IndexedRegion) { |
| start = ((IndexedRegion) o).getStartOffset(); |
| int end = ((IndexedRegion) o).getEndOffset(); |
| if (selectedObjects.length > 1) { |
| for (int i = 1; i < selectedObjects.length; i++) { |
| start = Math.min(start, ((IndexedRegion) selectedObjects[i]).getStartOffset()); |
| end = Math.max(end, ((IndexedRegion) selectedObjects[i]).getEndOffset()); |
| } |
| length = end - start; |
| } |
| } |
| else if (o instanceof ITextRegion) { |
| start = ((ITextRegion) o).getStart(); |
| int end = ((ITextRegion) o).getEnd(); |
| if (selectedObjects.length > 1) { |
| for (int i = 1; i < selectedObjects.length; i++) { |
| start = Math.min(start, ((ITextRegion) selectedObjects[i]).getStart()); |
| end = Math.max(end, ((ITextRegion) selectedObjects[i]).getEnd()); |
| } |
| length = end - start; |
| } |
| } |
| |
| if (start > -1) { |
| updated = new StructuredTextSelection(getDocument(), start, length, selectedObjects); |
| } |
| } |
| } |
| return updated; |
| } |
| } |
| |
| class TimeOutExpired extends TimerTask { |
| public void run() { |
| final byte[] result = new byte[1]; // Did the busy state end successfully? |
| getDisplay().syncExec(new Runnable() { |
| public void run() { |
| if (getDisplay() != null && !getDisplay().isDisposed()) |
| endBusyStateInternal(result); |
| } |
| }); |
| if (result[0] == 1) { |
| fBusyTimer.cancel(); |
| } |
| } |
| |
| } |
| |
| private class ConfigurationAndTarget { |
| private String fTargetId; |
| private StructuredTextViewerConfiguration fConfiguration; |
| |
| public ConfigurationAndTarget(String targetId, StructuredTextViewerConfiguration config) { |
| fTargetId = targetId; |
| fConfiguration = config; |
| } |
| |
| public String getTargetId() { |
| return fTargetId; |
| } |
| |
| public StructuredTextViewerConfiguration getConfiguration() { |
| return fConfiguration; |
| } |
| } |
| |
| private class CharacterPairListener implements VerifyKeyListener { |
| private CharacterPairing[] fInserters = new CharacterPairing[0]; |
| |
| /** |
| * Add the pairing to the list of inserters |
| * @param pairing |
| */ |
| void addInserter(CharacterPairing pairing) { |
| List pairings = new ArrayList(Arrays.asList(fInserters)); |
| pairings.add(pairing); |
| fInserters = (CharacterPairing[]) pairings.toArray(new CharacterPairing[pairings.size()]); |
| } |
| |
| void prioritize() { |
| Arrays.sort(fInserters); |
| } |
| |
| /** |
| * Perform cleanup on the character pair inserters |
| */ |
| void dispose() { |
| for (int i = 0; i < fInserters.length; i++) { |
| final AbstractCharacterPairInserter inserter = fInserters[i].inserter; |
| SafeRunner.run(new ISafeRunnable() { |
| public void handleException(Throwable exception) { |
| // rely on default logging |
| } |
| |
| public void run() throws Exception { |
| inserter.dispose(); |
| } |
| }); |
| } |
| } |
| |
| public void verifyKey(final VerifyEvent event) { |
| if (!event.doit || getInsertMode() != SMART_INSERT || isBlockSelectionModeEnabled() && isMultilineSelection()) |
| return; |
| final boolean[] paired = { false }; |
| for (int i = 0; i < fInserters.length; i++) { |
| final CharacterPairing pairing = fInserters[i]; |
| // use a SafeRunner -- this is a critical function (typing) |
| SafeRunner.run(new ISafeRunnable() { |
| public void run() throws Exception { |
| final AbstractCharacterPairInserter inserter = pairing.inserter; |
| if (inserter.hasPair(event.character)) { |
| if (pair(event, inserter, pairing.partitions)) |
| paired[0] = true; |
| } |
| } |
| |
| public void handleException(Throwable exception) { |
| // rely on default logging |
| } |
| }); |
| if (paired[0]) |
| return; |
| } |
| } |
| |
| private boolean pair(VerifyEvent event, AbstractCharacterPairInserter inserter, Set partitions) { |
| final ISourceViewer viewer = getSourceViewer(); |
| final IDocument document = getSourceViewer().getDocument(); |
| if (document != null) { |
| try { |
| final Point selection = viewer.getSelectedRange(); |
| final int offset = selection.x; |
| final ITypedRegion partition = document.getPartition(offset); |
| if (partitions.contains(partition.getType())) { |
| // Don't modify if the editor input cannot be changed |
| if (!validateEditorInputState()) |
| return false; |
| event.doit = !inserter.pair(viewer, event.character); |
| return true; |
| } |
| } catch (BadLocationException e) { |
| } |
| } |
| return false; |
| } |
| |
| private boolean isMultilineSelection() { |
| ISelection selection = getSelectionProvider().getSelection(); |
| if (selection instanceof ITextSelection) { |
| ITextSelection ts = (ITextSelection) selection; |
| return ts.getStartLine() != ts.getEndLine(); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Representation of a character pairing that includes its priority based on |
| * its content type and how close it is to the content type of the file |
| * in the editor. |
| */ |
| private class CharacterPairing implements Comparable { |
| int priority; |
| AbstractCharacterPairInserter inserter; |
| Set partitions; |
| public int compareTo(Object o) { |
| if (o == this) |
| return 0; |
| return this.priority - ((CharacterPairing) o).priority; |
| } |
| } |
| |
| private class PartListener implements IPartListener { |
| |
| private ITextEditor fEditor; |
| |
| public PartListener(ITextEditor editor) { |
| fEditor = editor; |
| } |
| |
| public void partActivated(IWorkbenchPart part) { |
| if (part.getAdapter(ITextEditor.class) == fEditor) { |
| IReconciler reconciler = getSourceViewerConfiguration().getReconciler(getSourceViewer()); |
| if (reconciler instanceof DocumentRegionProcessor) { |
| ((DocumentRegionProcessor) reconciler).forceReconciling(); |
| } |
| } |
| } |
| |
| public void partBroughtToTop(IWorkbenchPart part) { |
| } |
| |
| public void partClosed(IWorkbenchPart part) { |
| } |
| |
| public void partDeactivated(IWorkbenchPart part) { |
| } |
| |
| public void partOpened(IWorkbenchPart part) { |
| } |
| |
| } |
| |
| /** |
| * Not API. May be removed in the future. |
| */ |
| protected final static char[] BRACKETS = {'{', '}', '(', ')', '[', ']'}; |
| |
| private static final long BUSY_STATE_DELAY = 1000; |
| /** |
| * Not API. May be removed in the future. |
| */ |
| protected static final String DOT = "."; //$NON-NLS-1$ |
| private static final String EDITOR_CONTEXT_MENU_ID = "org.eclipse.wst.sse.ui.StructuredTextEditor.EditorContext"; //$NON-NLS-1$ |
| private static final String EDITOR_CONTEXT_MENU_SUFFIX = ".source.EditorContext"; //$NON-NLS-1$ |
| |
| /** Non-NLS strings */ |
| private static final String EDITOR_KEYBINDING_SCOPE_ID = "org.eclipse.wst.sse.ui.structuredTextEditorScope"; //$NON-NLS-1$ |
| /** |
| * Not API. May be removed in the future. |
| */ |
| public static final String GROUP_NAME_ADDITIONS = IWorkbenchActionConstants.MB_ADDITIONS; //$NON-NLS-1$ |
| |
| private static final String REDO_ACTION_DESC = SSEUIMessages.Redo___0___UI_; //$NON-NLS-1$ = "Redo: {0}." |
| private static final String REDO_ACTION_DESC_DEFAULT = SSEUIMessages.Redo_Text_Change__UI_; //$NON-NLS-1$ = "Redo Text Change." |
| private static final String REDO_ACTION_TEXT = SSEUIMessages._Redo__0___Ctrl_Y_UI_; //$NON-NLS-1$ = "&Redo {0} @Ctrl+Y" |
| private static final String REDO_ACTION_TEXT_DEFAULT = SSEUIMessages._Redo_Text_Change__Ctrl_Y_UI_; //$NON-NLS-1$ = "&Redo Text Change @Ctrl+Y" |
| private static final String RULER_CONTEXT_MENU_ID = "org.eclipse.wst.sse.ui.StructuredTextEditor.RulerContext"; //$NON-NLS-1$ |
| private static final String RULER_CONTEXT_MENU_SUFFIX = ".source.RulerContext"; //$NON-NLS-1$ |
| |
| private final static String UNDERSCORE = "_"; //$NON-NLS-1$ |
| /** Translatable strings */ |
| private static final String UNDO_ACTION_DESC = SSEUIMessages.Undo___0___UI_; //$NON-NLS-1$ = "Undo: {0}." |
| |
| private static final String UNDO_ACTION_DESC_DEFAULT = SSEUIMessages.Undo_Text_Change__UI_; //$NON-NLS-1$ = "Undo Text Change." |
| private static final String UNDO_ACTION_TEXT = SSEUIMessages._Undo__0___Ctrl_Z_UI_; //$NON-NLS-1$ = "&Undo {0} @Ctrl+Z" |
| private static final String UNDO_ACTION_TEXT_DEFAULT = SSEUIMessages._Undo_Text_Change__Ctrl_Z_UI_; //$NON-NLS-1$ = "&Undo Text Change @Ctrl+Z" |
| // development time/debug variables only |
| private int adapterRequests; |
| |
| private long adapterTime; |
| private boolean fBackgroundJobEnded; |
| private boolean fBusyState; |
| private Timer fBusyTimer; |
| boolean fDirtyBeforeDocumentEvent = false; |
| int validateEditCount = 0; |
| private ExtendedEditorDropTargetAdapter fDropAdapter; |
| private DropTarget fDropTarget; |
| boolean fEditorDisposed = false; |
| private IEditorPart fEditorPart; |
| private InternalModelStateListener fInternalModelStateListener; |
| private IContentOutlinePage fOutlinePage; |
| |
| private OutlinePageListener fOutlinePageListener = null; |
| /** This editor's projection support */ |
| private ProjectionSupport fProjectionSupport; |
| private IPropertySheetPage fPropertySheetPage; |
| |
| private ISourceReconcilingListener[] fReconcilingListeners = new ISourceReconcilingListener[0]; |
| private IPartListener fPartListener; |
| |
| /** The ruler context menu to be disposed. */ |
| private Menu fRulerContextMenu; |
| /** The ruler context menu manager to be disposed. */ |
| private MenuManager fRulerContextMenuManager; |
| |
| String[] fShowInTargetIds = new String[]{IPageLayout.ID_RES_NAV, IPageLayout.ID_PROJECT_EXPLORER, IPageLayout.ID_OUTLINE}; |
| |
| private IAction fShowPropertiesAction = null; |
| private IStructuredModel fStructuredModel; |
| StructuredSelectionProvider fStructuredSelectionProvider = null; |
| /** The text context menu to be disposed. */ |
| private Menu fTextContextMenu; |
| /** The text context menu manager to be disposed. */ |
| private MenuManager fTextContextMenuManager; |
| private String fViewerConfigurationTargetId; |
| /** The selection history of the editor */ |
| private SelectionHistory fSelectionHistory; |
| /** The information presenter. */ |
| private InformationPresenter fInformationPresenter; |
| private boolean fUpdateMenuTextPending; |
| /** The quick outline handler */ |
| private QuickOutlineHandler fOutlineHandler; |
| |
| private boolean shouldClose = false; |
| private long startPerfTime; |
| private boolean fisReleased; |
| /** |
| * The action group for folding. |
| */ |
| private FoldingActionGroup fFoldingGroup; |
| |
| private ILabelProvider fStatusLineLabelProvider; |
| |
| private SemanticHighlightingManager fSemanticManager; |
| |
| private boolean fSelectionChangedFromGoto = false; |
| |
| private final CharacterPairListener fPairInserter = new CharacterPairListener(); |
| |
| /** |
| * Creates a new Structured Text Editor. |
| */ |
| public StructuredTextEditor() { |
| super(); |
| initializeDocumentProvider(null); |
| } |
| |
| private IStructuredModel aboutToSaveModel() { |
| IStructuredModel model = getInternalModel(); |
| if (model != null) { |
| model.aboutToChangeModel(); |
| } |
| return model; |
| } |
| |
| protected void addSourceMenuActions(IMenuManager menu) { |
| IMenuManager subMenu= new MenuManager(SSEUIMessages.SourceMenu_label, IStructuredTextEditorActionConstants.SOURCE_CONTEXT_MENU_ID); |
| subMenu.add(new Separator(IStructuredTextEditorActionConstants.SOURCE_BEGIN)); |
| subMenu.add(new Separator(IStructuredTextEditorActionConstants.SOURCE_ADDITIONS)); |
| subMenu.add(new Separator(IStructuredTextEditorActionConstants.SOURCE_END)); |
| menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, subMenu); |
| } |
| |
| protected void addRefactorMenuActions(IMenuManager menu) { |
| IMenuManager subMenu = new MenuManager(SSEUIMessages.RefactorMenu_label, IStructuredTextEditorActionConstants.REFACTOR_CONTEXT_MENU_ID); |
| menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, subMenu); |
| } |
| |
| protected void addContextMenuActions(IMenuManager menu) { |
| // Only offer actions that affect the text if the viewer allows |
| // modification and supports any of these operations |
| |
| // Some Design editors (DTD) rely on this view for their own uses |
| menu.appendToGroup(IWorkbenchActionConstants.GROUP_ADD, fShowPropertiesAction); |
| } |
| |
| private void addExtendedContextMenuActions(IMenuManager menu) { |
| IEditorActionBarContributor c = getEditorSite().getActionBarContributor(); |
| if (c instanceof IPopupMenuContributor) { |
| ((IPopupMenuContributor) c).contributeToPopupMenu(menu); |
| } |
| else { |
| ExtendedEditorActionBuilder builder = new ExtendedEditorActionBuilder(); |
| IExtendedContributor pmc = builder.readActionExtensions(getConfigurationPoints()); |
| if (pmc != null) { |
| pmc.setActiveEditor(this); |
| pmc.contributeToPopupMenu(menu); |
| } |
| } |
| } |
| |
| protected void addExtendedRulerContextMenuActions(IMenuManager menu) { |
| // none at this level |
| } |
| |
| |
| |
| /** |
| * Starts background mode. |
| * <p> |
| * Not API. May be removed in the future. |
| * </p> |
| */ |
| void beginBackgroundOperation() { |
| fBackgroundJobEnded = false; |
| // if already in busy state, no need to do anything |
| // and, we only start, or reset, the timed busy |
| // state when we get the "endBackgroundOperation" call. |
| if (!inBusyState()) { |
| beginBusyStateInternal(); |
| } |
| } |
| |
| private void beginBusyStateInternal() { |
| |
| fBusyState = true; |
| startBusyTimer(); |
| |
| ISourceViewer viewer = getSourceViewer(); |
| if (viewer instanceof StructuredTextViewer) { |
| ((StructuredTextViewer) viewer).beginBackgroundUpdate(); |
| |
| } |
| showBusy(true); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.texteditor.ITextEditor#close(boolean) |
| */ |
| public void close(final boolean save) { |
| /* |
| * Instead of us closing directly, we have to close with our |
| * containing (multipage) editor, if it exists. |
| */ |
| if (getSite() == null) { |
| // if site hasn't been set yet, then we're not |
| // completely open |
| // so set a flag not to open |
| shouldClose = true; |
| } |
| else { |
| if (getEditorPart() != null) { |
| Display display = getSite().getShell().getDisplay(); |
| display.asyncExec(new Runnable() { |
| |
| public void run() { |
| getSite().getPage().closeEditor(getEditorPart(), save); |
| } |
| }); |
| } |
| else { |
| super.close(save); |
| } |
| } |
| } |
| |
| private void activateContexts(IContextService service) { |
| if(service == null) |
| return; |
| |
| String[] definitions = getDefinitions(getConfigurationPoints()); |
| |
| if(definitions != null) { |
| String[] contexts = null; |
| for(int i = 0; i < definitions.length; i++) { |
| contexts = StringUtils.unpack(definitions[i]); |
| for(int j = 0; j < contexts.length; j++) |
| service.activateContext(contexts[j].trim()); |
| } |
| } |
| |
| } |
| |
| private String[] getDefinitions(String[] ids) { |
| ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance(); |
| String[] definitions = null; |
| |
| /* Iterate through the configuration ids until one is found that has |
| * an activecontexts definition |
| */ |
| for(int i = 0; i < ids.length; i++) { |
| definitions = builder.getDefinitions("activecontexts", ids[i]); //$NON-NLS-1$ |
| if(definitions != null && definitions.length > 0) |
| return definitions; |
| } |
| return null; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#collectContextMenuPreferencePages() |
| */ |
| protected String[] collectContextMenuPreferencePages() { |
| List allIds = new ArrayList(0); |
| |
| // get contributed preference pages |
| ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance(); |
| String[] configurationIds = getConfigurationPoints(); |
| for (int i = 0; i < configurationIds.length; i++) { |
| String[] definitions = builder.getDefinitions("preferencepages", configurationIds[i]); //$NON-NLS-1$ |
| for (int j = 0; j < definitions.length; j++) { |
| String someIds = definitions[j]; |
| if (someIds != null && someIds.length() > 0) { |
| // supports multiple comma-delimited page IDs in one |
| // element |
| String[] ids = StringUtils.unpack(someIds); |
| for (int k = 0; k < ids.length; k++) { |
| // trim, just to keep things clean |
| String id = ids[k].trim(); |
| if (!allIds.contains(id)) { |
| allIds.add(id); |
| } |
| } |
| } |
| } |
| } |
| |
| // add pages contributed by super |
| String[] superPages = super.collectContextMenuPreferencePages(); |
| for (int m = 0; m < superPages.length; m++) { |
| // trim, just to keep things clean |
| String id = superPages[m].trim(); |
| if (!allIds.contains(id)) { |
| allIds.add(id); |
| } |
| } |
| |
| return (String[]) allIds.toArray(new String[0]); |
| } |
| |
| /** |
| * Compute and set double-click action for the vertical ruler |
| */ |
| private void computeAndSetDoubleClickAction() { |
| /* |
| * Make double-clicking on the ruler toggle a breakpoint instead of |
| * toggling a bookmark. For lines where a breakpoint won't be created, |
| * create a bookmark through the contributed RulerDoubleClick action. |
| */ |
| setAction(ITextEditorActionConstants.RULER_DOUBLE_CLICK, new ToggleBreakpointAction(this, getVerticalRuler(), getAction(ITextEditorActionConstants.RULER_DOUBLE_CLICK))); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.texteditor.ExtendedTextEditor#configureSourceViewerDecorationSupport(org.eclipse.ui.texteditor.SourceViewerDecorationSupport) |
| */ |
| protected void configureSourceViewerDecorationSupport(SourceViewerDecorationSupport support) { |
| support.setCharacterPairMatcher(createCharacterPairMatcher()); |
| support.setMatchingCharacterPainterPreferenceKeys(EditorPreferenceNames.MATCHING_BRACKETS, EditorPreferenceNames.MATCHING_BRACKETS_COLOR); |
| |
| super.configureSourceViewerDecorationSupport(support); |
| } |
| |
| protected void createActions() { |
| super.createActions(); |
| ResourceBundle resourceBundle = SSEUIMessages.getResourceBundle(); |
| IWorkbenchHelpSystem helpSystem = SSEUIPlugin.getDefault().getWorkbench().getHelpSystem(); |
| // TextView Action - moving the selected text to |
| // the clipboard |
| // override the cut/paste/delete action to make |
| // them run on read-only |
| // files |
| Action action = new TextOperationAction(resourceBundle, "Editor_Cut_", this, ITextOperationTarget.CUT); //$NON-NLS-1$ |
| action.setActionDefinitionId(IWorkbenchActionDefinitionIds.CUT); |
| setAction(ITextEditorActionConstants.CUT, action); |
| helpSystem.setHelp(action, IAbstractTextEditorHelpContextIds.CUT_ACTION); |
| // TextView Action - inserting the clipboard |
| // content at the current |
| // position |
| // override the cut/paste/delete action to make |
| // them run on read-only |
| // files |
| action = new TextOperationAction(resourceBundle, "Editor_Paste_", this, ITextOperationTarget.PASTE); //$NON-NLS-1$ |
| action.setActionDefinitionId(IWorkbenchActionDefinitionIds.PASTE); |
| setAction(ITextEditorActionConstants.PASTE, action); |
| helpSystem.setHelp(action, IAbstractTextEditorHelpContextIds.PASTE_ACTION); |
| // TextView Action - deleting the selected text or |
| // if selection is |
| // empty the character at the right of the current |
| // position |
| // override the cut/paste/delete action to make |
| // them run on read-only |
| // files |
| action = new TextOperationAction(resourceBundle, "Editor_Delete_", this, ITextOperationTarget.DELETE); //$NON-NLS-1$ |
| action.setActionDefinitionId(IWorkbenchActionDefinitionIds.DELETE); |
| setAction(ITextEditorActionConstants.DELETE, action); |
| helpSystem.setHelp(action, IAbstractTextEditorHelpContextIds.DELETE_ACTION); |
| // SourceView Action - requesting content assist to |
| // show completetion |
| // proposals for the current insert position |
| action = new TextOperationAction(resourceBundle, StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_PROPOSALS + UNDERSCORE, this, ISourceViewer.CONTENTASSIST_PROPOSALS); |
| helpSystem.setHelp(action, IHelpContextIds.CONTMNU_CONTENTASSIST_HELPID); |
| action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS); |
| setAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_PROPOSALS, action); |
| markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_PROPOSALS, true); |
| // SourceView Action - requesting content assist to |
| // show the content |
| // information for the current insert position |
| action = new TextOperationAction(SSEUIMessages.getResourceBundle(), StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_CONTEXT_INFORMATION + UNDERSCORE, this, ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION); |
| action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_CONTEXT_INFORMATION); |
| setAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_CONTEXT_INFORMATION, action); |
| markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_CONTEXT_INFORMATION, true); |
| // StructuredTextViewer Action - requesting format |
| // of the whole |
| // document |
| action = new TextOperationAction(resourceBundle, StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT + UNDERSCORE, this, StructuredTextViewer.FORMAT_DOCUMENT); |
| helpSystem.setHelp(action, IHelpContextIds.CONTMNU_FORMAT_DOC_HELPID); |
| action.setActionDefinitionId(ActionDefinitionIds.FORMAT_DOCUMENT); |
| setAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT, action); |
| markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT, true); |
| markAsSelectionDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT, true); |
| // StructuredTextViewer Action - requesting format |
| // of the active |
| // elements |
| action = new TextOperationAction(resourceBundle, StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS + UNDERSCORE, this, StructuredTextViewer.FORMAT_ACTIVE_ELEMENTS); |
| helpSystem.setHelp(action, IHelpContextIds.CONTMNU_FORMAT_ELEMENTS_HELPID); |
| action.setActionDefinitionId(ActionDefinitionIds.FORMAT_ACTIVE_ELEMENTS); |
| setAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS, action); |
| markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS, true); |
| markAsSelectionDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS, true); |
| |
| // StructuredTextEditor Action - add breakpoints (falling back to the |
| // current double-click if they can't be added) |
| action = new ToggleBreakpointAction(this, getVerticalRuler()); |
| setAction(ActionDefinitionIds.TOGGLE_BREAKPOINTS, action); |
| // StructuredTextEditor Action - manage breakpoints |
| action = new ManageBreakpointAction(this, getVerticalRuler()); |
| setAction(ActionDefinitionIds.MANAGE_BREAKPOINTS, action); |
| // StructuredTextEditor Action - edit breakpoints |
| action = new EditBreakpointAction(this, getVerticalRuler()); |
| setAction(ActionDefinitionIds.EDIT_BREAKPOINTS, action); |
| // StructuredTextViewer Action - open file on selection |
| action = new OpenHyperlinkAction(resourceBundle, StructuredTextEditorActionConstants.ACTION_NAME_OPEN_FILE + UNDERSCORE, this, getSourceViewer()); |
| action.setActionDefinitionId(ActionDefinitionIds.OPEN_FILE); |
| setAction(StructuredTextEditorActionConstants.ACTION_NAME_OPEN_FILE, action); |
| |
| computeAndSetDoubleClickAction(); |
| |
| IHandler handler = new GotoMatchingBracketHandler(); |
| IHandlerService handlerService = (IHandlerService) getSite().getService(IHandlerService.class); |
| if (handlerService != null) |
| handlerService.activateHandler(ActionDefinitionIds.GOTO_MATCHING_BRACKET, handler); |
| if (handlerService != null) { |
| fOutlineHandler = new QuickOutlineHandler(); |
| handlerService.activateHandler(ActionDefinitionIds.SHOW_OUTLINE, fOutlineHandler); |
| } |
| |
| fShowPropertiesAction = new ShowPropertiesAction(getEditorPart(), getSelectionProvider()); |
| fFoldingGroup = new FoldingActionGroup(this, getSourceViewer()); |
| } |
| |
| protected LineChangeHover createChangeHover() { |
| return super.createChangeHover(); //new StructuredLineChangeHover(); |
| } |
| |
| protected ICharacterPairMatcher createCharacterPairMatcher() { |
| ICharacterPairMatcher matcher = null; |
| ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance(); |
| String[] ids = getConfigurationPoints(); |
| for (int i = 0; matcher == null && i < ids.length; i++) { |
| matcher = (ICharacterPairMatcher) builder.getConfiguration(DocumentRegionEdgeMatcher.ID, ids[i]); |
| } |
| if (matcher == null) { |
| matcher = new DefaultCharacterPairMatcher(new char[]{'(', ')', '{', '}', '[', ']', '<', '>', '"', '"', '\'', '\''}); |
| } |
| return matcher; |
| } |
| |
| /** |
| * Create a preference store that combines the source editor preferences |
| * with the base editor's preferences. |
| * |
| * @return IPreferenceStore |
| */ |
| private IPreferenceStore createCombinedPreferenceStore() { |
| IPreferenceStore sseEditorPrefs = SSEUIPlugin.getDefault().getPreferenceStore(); |
| IPreferenceStore baseEditorPrefs = EditorsUI.getPreferenceStore(); |
| return new ChainedPreferenceStore(new IPreferenceStore[]{sseEditorPrefs, baseEditorPrefs}); |
| } |
| |
| private ContentOutlineConfiguration createContentOutlineConfiguration() { |
| ContentOutlineConfiguration cfg = null; |
| ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance(); |
| String[] ids = getConfigurationPoints(); |
| for (int i = 0; cfg == null && i < ids.length; i++) { |
| cfg = (ContentOutlineConfiguration) builder.getConfiguration(ExtendedConfigurationBuilder.CONTENTOUTLINECONFIGURATION, ids[i]); |
| } |
| return cfg; |
| } |
| |
| protected void createModelDependentFields() { |
| if (fStructuredSelectionProvider != null) { |
| SelectionConvertor convertor = (SelectionConvertor) fStructuredModel.getAdapter(SelectionConvertor.class); |
| if (convertor != null) |
| fStructuredSelectionProvider.selectionConvertor = convertor; |
| else |
| fStructuredSelectionProvider.selectionConvertor = new SelectionConvertor(); |
| } |
| } |
| |
| /** |
| * {@inheritDoc} |
| * <p> |
| * Use StructuredTextViewerConfiguration if a viewerconfiguration has not |
| * already been set. Also initialize StructuredTextViewer. |
| * </p> |
| * |
| * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createPartControl(org.eclipse.swt.widgets.Composite) |
| */ |
| public void createPartControl(Composite parent) { |
| IContextService contextService = (IContextService) getSite().getService(IContextService.class); |
| if (contextService != null) |
| contextService.activateContext(EDITOR_KEYBINDING_SCOPE_ID); |
| |
| if (getSourceViewerConfiguration() == null) { |
| ConfigurationAndTarget cat = createSourceViewerConfiguration(); |
| fViewerConfigurationTargetId = cat.getTargetId(); |
| StructuredTextViewerConfiguration newViewerConfiguration = cat.getConfiguration(); |
| setSourceViewerConfiguration(newViewerConfiguration); |
| } |
| |
| super.createPartControl(parent); |
| |
| // instead of calling setInput twice, use initializeSourceViewer() to |
| // handle source viewer initialization previously handled by setInput |
| initializeSourceViewer(); |
| |
| // update editor context menu, vertical ruler context menu, infopop |
| if (getInternalModel() != null) { |
| updateEditorControlsForContentType(getInternalModel().getContentTypeIdentifier()); |
| } |
| else { |
| updateEditorControlsForContentType(null); |
| } |
| |
| // used for Show Tooltip Description |
| IInformationControlCreator informationControlCreator = new IInformationControlCreator() { |
| public IInformationControl createInformationControl(Shell shell) { |
| boolean cutDown = false; |
| int style = cutDown ? SWT.NONE : (SWT.V_SCROLL | SWT.H_SCROLL); |
| return new DefaultInformationControl(shell, SWT.RESIZE | SWT.TOOL, style, new HTMLTextPresenter(cutDown)); |
| } |
| }; |
| |
| fInformationPresenter = new InformationPresenter(informationControlCreator); |
| fInformationPresenter.setSizeConstraints(60, 10, true, true); |
| fInformationPresenter.install(getSourceViewer()); |
| addReconcilingListeners(getSourceViewerConfiguration(), getTextViewer()); |
| fPartListener = new PartListener(this); |
| getSite().getWorkbenchWindow().getPartService().addPartListener(fPartListener); |
| installSemanticHighlighting(); |
| if (fOutlineHandler != null) { |
| IInformationPresenter presenter = configureOutlinePresenter(getSourceViewer(), getSourceViewerConfiguration()); |
| if (presenter != null) { |
| presenter.install(getSourceViewer()); |
| fOutlineHandler.configure(presenter); |
| } |
| } |
| installCharacterPairing(); |
| ISourceViewer viewer = getSourceViewer(); |
| if (viewer instanceof ITextViewerExtension) |
| ((ITextViewerExtension) viewer).appendVerifyKeyListener(fPairInserter); |
| |
| } |
| |
| protected PropertySheetConfiguration createPropertySheetConfiguration() { |
| PropertySheetConfiguration cfg = null; |
| ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance(); |
| String[] ids = getConfigurationPoints(); |
| for (int i = 0; cfg == null && i < ids.length; i++) { |
| cfg = (PropertySheetConfiguration) builder.getConfiguration(ExtendedConfigurationBuilder.PROPERTYSHEETCONFIGURATION, ids[i]); |
| } |
| return cfg; |
| } |
| |
| /** |
| * Loads the Show In Target IDs from the Extended Configuration extension |
| * point. |
| * |
| * @return |
| */ |
| private String[] createShowInTargetIds() { |
| List allIds = new ArrayList(0); |
| ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance(); |
| String[] configurationIds = getConfigurationPoints(); |
| for (int i = 0; i < configurationIds.length; i++) { |
| String[] definitions = builder.getDefinitions("showintarget", configurationIds[i]); //$NON-NLS-1$ |
| for (int j = 0; j < definitions.length; j++) { |
| String someIds = definitions[j]; |
| if (someIds != null && someIds.length() > 0) { |
| String[] ids = StringUtils.unpack(someIds); |
| for (int k = 0; k < ids.length; k++) { |
| // trim, just to keep things clean |
| String id = ids[k].trim(); |
| if (!allIds.contains(id)) { |
| allIds.add(id); |
| } |
| } |
| } |
| } |
| } |
| |
| if (!allIds.contains(IPageLayout.ID_RES_NAV)) { |
| allIds.add(IPageLayout.ID_RES_NAV); |
| } |
| if (!allIds.contains(IPageLayout.ID_PROJECT_EXPLORER)) { |
| allIds.add(IPageLayout.ID_PROJECT_EXPLORER); |
| } |
| if (!allIds.contains(IPageLayout.ID_OUTLINE)) { |
| allIds.add(IPageLayout.ID_OUTLINE); |
| } |
| return (String[]) allIds.toArray(new String[0]); |
| } |
| |
| /** |
| * @return |
| */ |
| private ISourceEditingTextTools createSourceEditingTextTools() { |
| ISourceEditingTextTools tools = null; |
| ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance(); |
| String[] ids = getConfigurationPoints(); |
| for (int i = 0; tools == null && i < ids.length; i++) { |
| tools = (ISourceEditingTextTools) builder.getConfiguration(NullSourceEditingTextTools.ID, ids[i]); |
| } |
| if (tools == null) { |
| tools = NullSourceEditingTextTools.getInstance(); |
| ((NullSourceEditingTextTools) tools).setTextEditor(this); |
| } |
| Method method = null; //$NON-NLS-1$ |
| try { |
| method = tools.getClass().getMethod("setTextEditor", new Class[]{StructuredTextEditor.class}); //$NON-NLS-1$ |
| } |
| catch (NoSuchMethodException e) { |
| } |
| if (method == null) { |
| try { |
| method = tools.getClass().getMethod("setTextEditor", new Class[]{ITextEditor.class}); //$NON-NLS-1$ |
| } |
| catch (NoSuchMethodException e) { |
| } |
| } |
| if (method == null) { |
| try { |
| method = tools.getClass().getMethod("setTextEditor", new Class[]{IEditorPart.class}); //$NON-NLS-1$ |
| } |
| catch (NoSuchMethodException e) { |
| } |
| } |
| if (method != null) { |
| if (!method.isAccessible()) { |
| method.setAccessible(true); |
| } |
| try { |
| method.invoke(tools, new Object[]{this}); |
| } |
| catch (Exception e) { |
| Logger.logException("Problem creating ISourceEditingTextTools implementation", e); //$NON-NLS-1$ |
| } |
| } |
| |
| return tools; |
| } |
| |
| /** |
| * Creates the source viewer to be used by this editor |
| */ |
| protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler verticalRuler, int styles) { |
| fAnnotationAccess = createAnnotationAccess(); |
| fOverviewRuler = createOverviewRuler(getSharedColors()); |
| StructuredTextViewer sourceViewer = createStructedTextViewer(parent, verticalRuler, styles); |
| initSourceViewer(sourceViewer); |
| return sourceViewer; |
| } |
| |
| private ConfigurationAndTarget createSourceViewerConfiguration() { |
| ConfigurationAndTarget cat = null; |
| StructuredTextViewerConfiguration cfg = null; |
| ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance(); |
| String[] ids = getConfigurationPoints(); |
| for (int i = 0; cfg == null && i < ids.length; i++) { |
| cfg = (StructuredTextViewerConfiguration) builder.getConfiguration(ExtendedConfigurationBuilder.SOURCEVIEWERCONFIGURATION, ids[i]); |
| cat = new ConfigurationAndTarget(ids[i], cfg); |
| } |
| if (cfg == null) { |
| cfg = new StructuredTextViewerConfiguration(); |
| String targetid = getClass().getName() + "#default"; //$NON-NLS-1$ |
| cat = new ConfigurationAndTarget(targetid, cfg); |
| } |
| return cat; |
| } |
| |
| protected StructuredTextViewer createStructedTextViewer(Composite parent, IVerticalRuler verticalRuler, int styles) { |
| return new StructuredTextViewer(parent, verticalRuler, getOverviewRuler(), isOverviewRulerVisible(), styles); |
| } |
| |
| protected void createUndoRedoActions() { |
| // overridden to add icons to actions |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=111877 |
| super.createUndoRedoActions(); |
| IAction action = getAction(ITextEditorActionConstants.UNDO); |
| if (action != null) { |
| action.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_UNDO)); |
| } |
| |
| action = getAction(ITextEditorActionConstants.REDO); |
| if (action != null) { |
| action.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_REDO)); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.IWorkbenchPart#dispose() |
| */ |
| public void dispose() { |
| Logger.trace("Source Editor", "StructuredTextEditor::dispose entry"); //$NON-NLS-1$ //$NON-NLS-2$ |
| if (org.eclipse.wst.sse.core.internal.util.Debug.perfTestAdapterClassLoading) { |
| System.out.println("Total calls to getAdapter: " + adapterRequests); //$NON-NLS-1$ |
| System.out.println("Total time in getAdapter: " + adapterTime); //$NON-NLS-1$ |
| System.out.println("Average time per call: " + (adapterTime / adapterRequests)); //$NON-NLS-1$ |
| } |
| |
| ISourceViewer viewer = getSourceViewer(); |
| if (viewer instanceof ITextViewerExtension) |
| ((ITextViewerExtension) viewer).removeVerifyKeyListener(fPairInserter); |
| |
| // dispose of information presenter |
| if (fInformationPresenter != null) { |
| fInformationPresenter.dispose(); |
| fInformationPresenter = null; |
| } |
| |
| if (fOutlineHandler != null) { |
| fOutlineHandler.dispose(); |
| } |
| // dispose of selection history |
| if (fSelectionHistory != null) { |
| fSelectionHistory.dispose(); |
| fSelectionHistory = null; |
| } |
| |
| if (fProjectionSupport != null) { |
| fProjectionSupport.dispose(); |
| fProjectionSupport = null; |
| } |
| |
| if (fFoldingGroup != null) { |
| fFoldingGroup.dispose(); |
| fFoldingGroup = null; |
| } |
| |
| // dispose of menus that were being tracked |
| if (fTextContextMenu != null) { |
| fTextContextMenu.dispose(); |
| } |
| if (fRulerContextMenu != null) { |
| fRulerContextMenu.dispose(); |
| } |
| if (fTextContextMenuManager != null) { |
| fTextContextMenuManager.removeMenuListener(getContextMenuListener()); |
| fTextContextMenuManager.removeAll(); |
| fTextContextMenuManager.dispose(); |
| } |
| if (fRulerContextMenuManager != null) { |
| fRulerContextMenuManager.removeMenuListener(getContextMenuListener()); |
| fRulerContextMenuManager.removeAll(); |
| fRulerContextMenuManager.dispose(); |
| } |
| |
| // added this 2/20/2004 based on probe results -- |
| // seems should be handled by setModel(null), but |
| // that's a more radical change. |
| // and, technically speaking, should not be needed, |
| // but makes a memory leak |
| // less severe. |
| if (fStructuredModel != null) { |
| fStructuredModel.removeModelStateListener(getInternalModelStateListener()); |
| } |
| |
| // BUG155335 - if there was no document provider, there was nothing |
| // added |
| // to document, so nothing to remove |
| if (getDocumentProvider() != null) { |
| IDocument doc = getDocumentProvider().getDocument(getEditorInput()); |
| if (doc != null) { |
| if (doc instanceof IExecutionDelegatable) { |
| ((IExecutionDelegatable) doc).setExecutionDelegate(null); |
| } |
| } |
| } |
| |
| // some things in the configuration need to clean |
| // up after themselves |
| if (fOutlinePage != null) { |
| if (fOutlinePage instanceof ConfigurableContentOutlinePage && fOutlinePageListener != null) { |
| ((ConfigurableContentOutlinePage) fOutlinePage).removeDoubleClickListener(fOutlinePageListener); |
| } |
| if (fOutlinePageListener != null) { |
| fOutlinePage.removeSelectionChangedListener(fOutlinePageListener); |
| } |
| } |
| |
| fEditorDisposed = true; |
| disposeModelDependentFields(); |
| |
| if (fDropTarget != null) |
| fDropTarget.dispose(); |
| |
| if (fPartListener != null) { |
| getSite().getWorkbenchWindow().getPartService().removePartListener(fPartListener); |
| fPartListener = null; |
| } |
| |
| uninstallSemanticHighlighting(); |
| |
| if (fPairInserter != null) |
| fPairInserter.dispose(); |
| |
| |
| setPreferenceStore(null); |
| |
| /* |
| * Strictly speaking, but following null outs should not be needed, |
| * but in the event of a memory leak, they make the memory leak less |
| * severe |
| */ |
| fDropAdapter = null; |
| fDropTarget = null; |
| |
| if (fStructuredSelectionProvider != null) { |
| fStructuredSelectionProvider.dispose(); |
| } |
| |
| setStatusLineMessage(null); |
| |
| super.dispose(); |
| |
| Logger.trace("Source Editor", "StructuredTextEditor::dispose exit"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#disposeDocumentProvider() |
| */ |
| protected void disposeDocumentProvider() { |
| if (fStructuredModel != null && !fisReleased && !(getDocumentProvider() instanceof IModelProvider)) { |
| fStructuredModel.releaseFromEdit(); |
| fisReleased = true; |
| } |
| super.disposeDocumentProvider(); |
| } |
| |
| /** |
| * Disposes model specific editor helpers such as statusLineHelper. |
| * Basically any code repeated in update() & dispose() should be placed |
| * here. |
| */ |
| private void disposeModelDependentFields() { |
| if(fStructuredSelectionProvider != null) |
| fStructuredSelectionProvider.selectionConvertor = new SelectionConvertor(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.texteditor.ITextEditor#doRevertToSaved() |
| */ |
| public void doRevertToSaved() { |
| super.doRevertToSaved(); |
| if (fOutlinePage != null && fOutlinePage instanceof IUpdate) { |
| ((IUpdate) fOutlinePage).update(); |
| } |
| // reset undo |
| IDocument doc = getDocumentProvider().getDocument(getEditorInput()); |
| if (doc instanceof IStructuredDocument) { |
| ((IStructuredDocument) doc).getUndoManager().getCommandStack().flush(); |
| } |
| |
| // update menu text |
| updateMenuText(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| public void doSave(IProgressMonitor progressMonitor) { |
| IStructuredModel model = null; |
| try { |
| model = aboutToSaveModel(); |
| updateEncodingMemento(); |
| super.doSave(progressMonitor); |
| } |
| finally { |
| savedModel(model); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.texteditor.AbstractTextEditor#doSetInput(org.eclipse.ui.IEditorInput) |
| */ |
| protected void doSetInput(IEditorInput input) throws CoreException { |
| IEditorInput oldInput = getEditorInput(); |
| if (oldInput != null) { |
| IDocument olddoc = getDocumentProvider().getDocument(oldInput); |
| if (olddoc != null && olddoc instanceof IExecutionDelegatable) { |
| ((IExecutionDelegatable) olddoc).setExecutionDelegate(null); |
| } |
| } |
| |
| if (fStructuredModel != null && !(getDocumentProvider() instanceof IModelProvider)) { |
| fStructuredModel.releaseFromEdit(); |
| } |
| |
| //attempt to get the model for the given input |
| super.doSetInput(input); |
| IStructuredModel model = tryToGetModel(input); |
| |
| /* if could not get the model prompt user to update content type |
| * if preferences allow, then try to get model again |
| */ |
| if(model == null && SSEUIPlugin.getDefault().getPreferenceStore().getBoolean(EditorPreferenceNames.SHOW_UNKNOWN_CONTENT_TYPE_MSG)) { |
| // display a dialog informing user of unknown content type giving them chance to update preferences |
| UnknownContentTypeDialog dialog = new UnknownContentTypeDialog(getSite().getShell(), SSEUIPlugin.getDefault().getPreferenceStore(), EditorPreferenceNames.SHOW_UNKNOWN_CONTENT_TYPE_MSG); |
| dialog.open(); |
| |
| //try to get model again in hopes user updated preferences |
| super.doSetInput(input); |
| model = tryToGetModel(input); |
| |
| //still could not get the model to open this editor so log |
| if(model == null) { |
| logUnexpectedDocumentKind(input); |
| } |
| } |
| |
| if (fStructuredModel != null || model != null) { |
| setModel(model); |
| } |
| |
| if (getInternalModel() != null) { |
| updateEditorControlsForContentType(getInternalModel().getContentTypeIdentifier()); |
| } |
| else { |
| updateEditorControlsForContentType(null); |
| } |
| |
| // start editor with smart insert mode |
| setInsertMode(SMART_INSERT); |
| } |
| |
| /** |
| * <p>Attempts to get the {@link IStructuredModel} for the given {@link IEditorInput}</p> |
| * |
| * @param input the {@link IEditorInput} to try and get the {@link IStructuredModel} for |
| * |
| * @return The {@link IStructuredModel} associated with the given {@link IEditorInput} or |
| * <code>null</code> if no associated {@link IStructuredModel} could be found. |
| */ |
| private IStructuredModel tryToGetModel(IEditorInput input) { |
| IStructuredModel model = null; |
| |
| IDocument newDocument = getDocumentProvider().getDocument(input); |
| if (newDocument instanceof IExecutionDelegatable) { |
| ((IExecutionDelegatable) newDocument).setExecutionDelegate(new EditorExecutionContext(this)); |
| } |
| |
| // if we have a Model provider, get the model from it |
| if (getDocumentProvider() instanceof IModelProvider) { |
| model = ((IModelProvider) getDocumentProvider()).getModel(getEditorInput()); |
| if (!model.isShared()) { |
| EditorModelUtil.addFactoriesTo(model); |
| } |
| } |
| else if (newDocument instanceof IStructuredDocument) { |
| // corresponding releaseFromEdit occurs in dispose() |
| model = StructuredModelManager.getModelManager().getModelForEdit((IStructuredDocument) newDocument); |
| EditorModelUtil.addFactoriesTo(model); |
| } |
| |
| return model; |
| } |
| |
| /** |
| * Sets up this editor's context menu before it is made visible. |
| * <p> |
| * Not API. May be reduced to protected method in the future. |
| * </p> |
| * |
| * @param menu |
| * the menu |
| */ |
| public void editorContextMenuAboutToShow(IMenuManager menu) { |
| /* |
| * To be consistent with the Java Editor, we want to remove ShiftRight |
| * and ShiftLeft from the context menu. |
| */ |
| super.editorContextMenuAboutToShow(menu); |
| menu.remove(ITextEditorActionConstants.SHIFT_LEFT); |
| menu.remove(ITextEditorActionConstants.SHIFT_RIGHT); |
| |
| addContextMenuActions(menu); |
| addSourceMenuActions(menu); |
| addRefactorMenuActions(menu); |
| addExtendedContextMenuActions(menu); |
| } |
| |
| /** |
| * End background mode. |
| * <p> |
| * Not API. May be removed in the future. |
| * </p> |
| */ |
| void endBackgroundOperation() { |
| fBackgroundJobEnded = true; |
| // note, we don't immediately end our 'internal busy' state, |
| // since we may get many calls in a short period of |
| // time. We always wait for the time out. |
| resetBusyState(); |
| } |
| |
| /** |
| * Note this method can be called indirectly from background job operation |
| * ... but expected to be gaurded there with ILock, plus, can be called |
| * directly from timer thread, so the timer's run method guards with ILock |
| * too. |
| * |
| * Set result[0] to 1 if the busy state was ended successfully |
| */ |
| private void endBusyStateInternal(byte[] result) { |
| if (fBackgroundJobEnded) { |
| result[0] = 1; |
| showBusy(false); |
| |
| ISourceViewer viewer = getSourceViewer(); |
| if (viewer instanceof StructuredTextViewer) { |
| ((StructuredTextViewer) viewer).endBackgroundUpdate(); |
| } |
| fBusyState = false; |
| } |
| else { |
| // we will only be in this branch for a back ground job that is |
| // taking |
| // longer than our normal time-out period (meaning we got notified |
| // of |
| // the timeout "inbetween" calls to 'begin' and |
| // 'endBackgroundOperation'. |
| // (which, remember, can only happen since there are many calls to |
| // begin/end in a short period of time, and we only "reset" on the |
| // 'ends'). |
| // In this event, there's really nothing to do, we're still in |
| // "busy state" |
| // and should start a new reset cycle once endBackgroundjob is |
| // called. |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) |
| */ |
| public Object getAdapter(Class required) { |
| if (org.eclipse.wst.sse.core.internal.util.Debug.perfTestAdapterClassLoading) { |
| startPerfTime = System.currentTimeMillis(); |
| } |
| Object result = null; |
| // text editor |
| IStructuredModel internalModel = getInternalModel(); |
| if (ITextEditor.class.equals(required) || ITextEditorExtension5.class.equals(required) || ITextEditorExtension4.class.equals(required) || ITextEditorExtension3.class.equals(required) || ITextEditorExtension2.class.equals(required) || ITextEditorExtension.class.equals(required)) { |
| result = this; |
| } |
| else if (IWorkbenchSiteProgressService.class.equals(required)) { |
| return getEditorPart().getSite().getAdapter(IWorkbenchSiteProgressService.class); |
| } |
| // content outline page |
| else if (IContentOutlinePage.class.equals(required)) { |
| if (fOutlinePage == null || fOutlinePage.getControl() == null || fOutlinePage.getControl().isDisposed()) { |
| ContentOutlineConfiguration cfg = createContentOutlineConfiguration(); |
| if (cfg != null) { |
| ConfigurableContentOutlinePage outlinePage = new ConfigurableContentOutlinePage(); |
| outlinePage.setConfiguration(cfg); |
| if (internalModel != null) { |
| outlinePage.setInputContentTypeIdentifier(internalModel.getContentTypeIdentifier()); |
| outlinePage.setInput(internalModel); |
| } |
| |
| if (fOutlinePageListener == null) { |
| fOutlinePageListener = new OutlinePageListener(); |
| } |
| |
| outlinePage.addSelectionChangedListener(fOutlinePageListener); |
| outlinePage.addDoubleClickListener(fOutlinePageListener); |
| |
| fOutlinePage = outlinePage; |
| } |
| } |
| result = fOutlinePage; |
| } |
| // property sheet page, but only if the input's editable |
| else if (IPropertySheetPage.class.equals(required) && isEditable()) { |
| if (fPropertySheetPage == null || fPropertySheetPage.getControl() == null || fPropertySheetPage.getControl().isDisposed()) { |
| PropertySheetConfiguration cfg = createPropertySheetConfiguration(); |
| if (cfg != null) { |
| ConfigurablePropertySheetPage propertySheetPage = new ConfigurablePropertySheetPage(); |
| propertySheetPage.setConfiguration(cfg); |
| fPropertySheetPage = propertySheetPage; |
| } |
| } |
| result = fPropertySheetPage; |
| } |
| else if (IDocument.class.equals(required)) { |
| result = getDocumentProvider().getDocument(getEditorInput()); |
| } |
| else if (ISourceEditingTextTools.class.equals(required)) { |
| result = createSourceEditingTextTools(); |
| } |
| else if (IToggleBreakpointsTarget.class.equals(required)) { |
| result = ToggleBreakpointsTarget.getInstance(); |
| } |
| else if (ITextEditorExtension4.class.equals(required)) { |
| result = this; |
| } |
| else if (IShowInTargetList.class.equals(required)) { |
| result = new ShowInTargetListAdapter(); |
| } |
| else if (IVerticalRuler.class.equals(required)) { |
| return getVerticalRuler(); |
| } |
| else if (SelectionHistory.class.equals(required)) { |
| if (fSelectionHistory == null) |
| fSelectionHistory = new SelectionHistory(this); |
| result = fSelectionHistory; |
| } |
| else if (IResource.class.equals(required)) { |
| IEditorInput input = getEditorInput(); |
| if (input != null) { |
| result = input.getAdapter(required); |
| } |
| } |
| else { |
| if (result == null && internalModel != null) { |
| result = internalModel.getAdapter(required); |
| } |
| // others |
| if (result == null) |
| result = super.getAdapter(required); |
| } |
| if (result == null) { |
| // Logger.log(Logger.INFO_DEBUG, "StructuredTextEditor.getAdapter returning null for " + required); //$NON-NLS-1$ |
| } |
| if (org.eclipse.wst.sse.core.internal.util.Debug.perfTestAdapterClassLoading) { |
| long stop = System.currentTimeMillis(); |
| adapterRequests++; |
| adapterTime += (stop - startPerfTime); |
| } |
| if (org.eclipse.wst.sse.core.internal.util.Debug.perfTestAdapterClassLoading) { |
| System.out.println("Total calls to getAdapter: " + adapterRequests); //$NON-NLS-1$ |
| System.out.println("Total time in getAdapter: " + adapterTime); //$NON-NLS-1$ |
| System.out.println("Average time per call: " + (adapterTime / adapterRequests)); //$NON-NLS-1$ |
| } |
| return result; |
| } |
| |
| private String[] getConfigurationPoints() { |
| String contentTypeIdentifierID = null; |
| if (getInternalModel() != null) { |
| contentTypeIdentifierID = getInternalModel().getContentTypeIdentifier(); |
| } |
| return ConfigurationPointCalculator.getConfigurationPoints(this, contentTypeIdentifierID, ConfigurationPointCalculator.SOURCE, StructuredTextEditor.class); |
| } |
| |
| /** |
| * added checks to overcome bug such that if we are shutting down in an |
| * error condition, then viewer will have already been disposed. |
| */ |
| protected String getCursorPosition() { |
| String result = null; |
| // this may be too expensive in terms of |
| // performance, to do this check |
| // every time, just to gaurd against error |
| // condition. |
| // perhaps there's a better way? |
| if (getSourceViewer() != null && getSourceViewer().getTextWidget() != null && !getSourceViewer().getTextWidget().isDisposed()) { |
| result = super.getCursorPosition(); |
| } |
| else { |
| result = "0:0"; //$NON-NLS-1$ |
| } |
| return result; |
| } |
| |
| |
| Display getDisplay() { |
| return PlatformUI.getWorkbench().getDisplay(); |
| } |
| |
| /** |
| * Returns this editor part. |
| * <p> |
| * Not API. May be removed in the future. |
| * </p> |
| * |
| * @return this editor part |
| */ |
| public IEditorPart getEditorPart() { |
| if (fEditorPart == null) |
| return this; |
| return fEditorPart; |
| } |
| |
| IStructuredModel getInternalModel() { |
| return fStructuredModel; |
| } |
| |
| private InternalModelStateListener getInternalModelStateListener() { |
| if (fInternalModelStateListener == null) { |
| fInternalModelStateListener = new InternalModelStateListener(); |
| } |
| return fInternalModelStateListener; |
| } |
| |
| /** |
| * Returns this editor's StructuredModel. |
| * <p> |
| * Not API. Will be removed in the future. |
| * </p> |
| * |
| * @return returns this editor's IStructuredModel |
| * @deprecated - This method allowed for uncontrolled access to the model |
| * instance and will be removed in the future. It is |
| * recommended that the current document provider be asked for |
| * the current document and the IModelManager then asked for |
| * the corresponding model with |
| * getExistingModelFor*(IDocument). Supported document |
| * providers ensure that the document maps to a shared |
| * structured model. |
| */ |
| public IStructuredModel getModel() { |
| IDocumentProvider documentProvider = getDocumentProvider(); |
| |
| if (documentProvider == null) { |
| // this indicated an error in startup sequence |
| Logger.trace(getClass().getName(), "Program Info Only: document provider was null when model requested"); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| // Remember if we entered this method without a model existing |
| boolean initialModelNull = (fStructuredModel == null); |
| |
| if (fStructuredModel == null && documentProvider != null) { |
| // lazily set the model instance, although this is an ABNORMAL |
| // CODE PATH |
| if (documentProvider instanceof IModelProvider) { |
| fStructuredModel = ((IModelProvider) documentProvider).getModel(getEditorInput()); |
| fisReleased = false; |
| } |
| else { |
| IDocument doc = documentProvider.getDocument(getEditorInput()); |
| if (doc instanceof IStructuredDocument) { |
| /* |
| * Called in this manner because getExistingModel can skip |
| * some calculations always performed in getModelForEdit |
| */ |
| IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForEdit(doc); |
| if (model == null) { |
| model = StructuredModelManager.getModelManager().getModelForEdit((IStructuredDocument) doc); |
| } |
| fStructuredModel = model; |
| fisReleased = false; |
| } |
| } |
| |
| EditorModelUtil.addFactoriesTo(fStructuredModel); |
| |
| if (initialModelNull && fStructuredModel != null) { |
| /* |
| * DMW: 9/1/2002 -- why is update called here? No change has |
| * been indicated? I'd like to remove, but will leave for now |
| * to avoid breaking this hack. Should measure/breakpoint to |
| * see how large the problem is. May cause performance |
| * problems. |
| * |
| * DMW: 9/8/2002 -- not sure why this was here initially, but |
| * the intent/hack must have been to call update if this was |
| * the first time fStructuredModel was set. So, I added the |
| * logic to check for that "first time" case. It would appear |
| * we don't really need. may remove in future when can test |
| * more. |
| */ |
| update(); |
| } |
| } |
| return fStructuredModel; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.part.IWorkbenchPartOrientation#getOrientation() |
| */ |
| public int getOrientation() { |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=88714 |
| return SWT.LEFT_TO_RIGHT; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.texteditor.ITextEditor#getSelectionProvider() |
| */ |
| public ISelectionProvider getSelectionProvider() { |
| if (fStructuredSelectionProvider == null) { |
| ISelectionProvider parentProvider = super.getSelectionProvider(); |
| if (parentProvider != null) { |
| fStructuredSelectionProvider = new StructuredSelectionProvider(parentProvider, this); |
| fStructuredSelectionProvider.addPostSelectionChangedListener(new ISelectionChangedListener() { |
| public void selectionChanged(SelectionChangedEvent event) { |
| updateStatusLine(event.getSelection()); |
| } |
| }); |
| if (fStructuredModel != null) { |
| SelectionConvertor convertor = (SelectionConvertor) fStructuredModel.getAdapter(SelectionConvertor.class); |
| if (convertor != null) { |
| fStructuredSelectionProvider.selectionConvertor = convertor; |
| } |
| } |
| } |
| } |
| if (fStructuredSelectionProvider == null) { |
| return super.getSelectionProvider(); |
| } |
| return fStructuredSelectionProvider; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.texteditor.AbstractTextEditor#getStatusLineManager() |
| * |
| * Overridden to use the top-level editor part's status line |
| */ |
| protected IStatusLineManager getStatusLineManager() { |
| return getEditorPart().getEditorSite().getActionBars().getStatusLineManager(); |
| } |
| |
| /** |
| * Returns the editor's source viewer. This method was created to expose |
| * the protected final getSourceViewer() method. |
| * <p> |
| * Not API. May be removed in the future. |
| * </p> |
| * |
| * @return the editor's source viewer |
| */ |
| public StructuredTextViewer getTextViewer() { |
| return (StructuredTextViewer) getSourceViewer(); |
| } |
| |
| /** |
| * Jumps to the matching bracket. |
| */ |
| void gotoMatchingBracket() { |
| ICharacterPairMatcher matcher = createCharacterPairMatcher(); |
| if (matcher == null) |
| return; |
| |
| ISourceViewer sourceViewer = getSourceViewer(); |
| IDocument document = sourceViewer.getDocument(); |
| if (document == null) |
| return; |
| |
| IRegion selection = getSignedSelection(sourceViewer); |
| |
| int selectionLength = Math.abs(selection.getLength()); |
| if (selectionLength > 1) { |
| setStatusLineErrorMessage(SSEUIMessages.GotoMatchingBracket_error_invalidSelection); |
| sourceViewer.getTextWidget().getDisplay().beep(); |
| return; |
| } |
| |
| int sourceCaretOffset = selection.getOffset() + selection.getLength(); |
| IRegion region = matcher.match(document, sourceCaretOffset); |
| if (region == null) { |
| setStatusLineErrorMessage(SSEUIMessages.GotoMatchingBracket_error_noMatchingBracket); |
| sourceViewer.getTextWidget().getDisplay().beep(); |
| return; |
| } |
| |
| int offset = region.getOffset(); |
| int length = region.getLength(); |
| |
| if (length < 1) |
| return; |
| |
| int anchor = matcher.getAnchor(); |
| |
| // go to after the match if matching to the right |
| int targetOffset = (ICharacterPairMatcher.RIGHT == anchor) ? offset : offset + length; |
| |
| boolean visible = false; |
| if (sourceViewer instanceof ITextViewerExtension5) { |
| ITextViewerExtension5 extension = (ITextViewerExtension5) sourceViewer; |
| visible = (extension.modelOffset2WidgetOffset(targetOffset) > -1); |
| } |
| else { |
| IRegion visibleRegion = sourceViewer.getVisibleRegion(); |
| // http://dev.eclipse.org/bugs/show_bug.cgi?id=34195 |
| visible = (targetOffset >= visibleRegion.getOffset() && targetOffset <= visibleRegion.getOffset() + visibleRegion.getLength()); |
| } |
| |
| if (!visible) { |
| setStatusLineErrorMessage(SSEUIMessages.GotoMatchingBracket_error_bracketOutsideSelectedElement); |
| sourceViewer.getTextWidget().getDisplay().beep(); |
| return; |
| } |
| |
| if (selection.getLength() < 0) |
| targetOffset -= selection.getLength(); |
| |
| if (sourceViewer != null) { |
| sourceViewer.setSelectedRange(targetOffset, selection.getLength()); |
| sourceViewer.revealRange(targetOffset, selection.getLength()); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.texteditor.AbstractTextEditor#handleCursorPositionChanged() |
| */ |
| protected void handleCursorPositionChanged() { |
| super.handleCursorPositionChanged(); |
| updateStatusField(StructuredTextEditorActionConstants.STATUS_CATEGORY_OFFSET); |
| } |
| |
| protected void handleElementContentReplaced() { |
| super.handleElementContentReplaced(); |
| |
| // queue a full revalidation of content |
| IDocument document = getDocumentProvider().getDocument(getEditorInput()); |
| SourceViewerConfiguration sourceViewerConfiguration = getSourceViewerConfiguration(); |
| if (document != null && sourceViewerConfiguration != null && sourceViewerConfiguration.getReconciler(getSourceViewer()) instanceof DirtyRegionProcessor) { |
| ((DirtyRegionProcessor) sourceViewerConfiguration.getReconciler(getSourceViewer())).processDirtyRegion(new DirtyRegion(0, document.getLength(), DirtyRegion.INSERT, document.get())); |
| } |
| |
| // https://bugs.eclipse.org/bugs/show_bug.cgi?id=129906 - update selection to listeners |
| ISelectionProvider selectionProvider = getSelectionProvider(); |
| ISelection originalSelection = selectionProvider.getSelection(); |
| if (selectionProvider instanceof StructuredSelectionProvider && originalSelection instanceof ITextSelection) { |
| SelectionChangedEvent syntheticEvent = new SelectionChangedEvent(selectionProvider, new TextSelection(((ITextSelection) originalSelection).getOffset(), ((ITextSelection) originalSelection).getLength())); |
| ((StructuredSelectionProvider) selectionProvider).handleSelectionChanged(syntheticEvent); |
| ((StructuredSelectionProvider) selectionProvider).handlePostSelectionChanged(syntheticEvent); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.texteditor.AbstractTextEditor#handlePreferenceStoreChanged(org.eclipse.jface.util.PropertyChangeEvent) |
| */ |
| protected void handlePreferenceStoreChanged(PropertyChangeEvent event) { |
| String property = event.getProperty(); |
| |
| if (EditorPreferenceNames.EDITOR_TEXT_HOVER_MODIFIERS.equals(property)) { |
| updateHoverBehavior(); |
| } |
| |
| //enable or disable as you type validation |
| else if(CommonEditorPreferenceNames.EVALUATE_TEMPORARY_PROBLEMS.equals(property)) { |
| IReconciler reconciler = this.getSourceViewerConfiguration().getReconciler(this.getSourceViewer()); |
| if (reconciler instanceof DocumentRegionProcessor) { |
| ((DocumentRegionProcessor) reconciler).setValidatorStrategyEnabled(isValidationEnabled()); |
| } |
| } |
| |
| else if (AbstractStructuredFoldingStrategy.FOLDING_ENABLED.equals(property)) { |
| if (getSourceViewer() instanceof ProjectionViewer) { |
| // install projection support if it has not even been |
| // installed yet |
| if (isFoldingEnabled() && (fProjectionSupport == null)) { |
| installProjectionSupport(); |
| } |
| ProjectionViewer pv = (ProjectionViewer) getSourceViewer(); |
| if (pv.isProjectionMode() != isFoldingEnabled()) { |
| if (pv.canDoOperation(ProjectionViewer.TOGGLE)) { |
| pv.doOperation(ProjectionViewer.TOGGLE); |
| } |
| } |
| } |
| } |
| |
| // update content assist preferences |
| else if (EditorPreferenceNames.CODEASSIST_PROPOSALS_BACKGROUND.equals(property)) { |
| ISourceViewer sourceViewer = getSourceViewer(); |
| if (sourceViewer != null) { |
| SourceViewerConfiguration configuration = getSourceViewerConfiguration(); |
| if (configuration != null) { |
| IContentAssistant contentAssistant = configuration.getContentAssistant(sourceViewer); |
| if (contentAssistant instanceof ContentAssistant) { |
| ContentAssistant assistant = (ContentAssistant) contentAssistant; |
| RGB rgb = PreferenceConverter.getColor(getPreferenceStore(), EditorPreferenceNames.CODEASSIST_PROPOSALS_BACKGROUND); |
| Color color = EditorUtility.getColor(rgb); |
| assistant.setProposalSelectorBackground(color); |
| } |
| } |
| } |
| } |
| |
| // update content assist preferences |
| else if (EditorPreferenceNames.CODEASSIST_PROPOSALS_FOREGROUND.equals(property)) { |
| ISourceViewer sourceViewer = getSourceViewer(); |
| if (sourceViewer != null) { |
| SourceViewerConfiguration configuration = getSourceViewerConfiguration(); |
| if (configuration != null) { |
| IContentAssistant contentAssistant = configuration.getContentAssistant(sourceViewer); |
| if (contentAssistant instanceof ContentAssistant) { |
| ContentAssistant assistant = (ContentAssistant) contentAssistant; |
| RGB rgb = PreferenceConverter.getColor(getPreferenceStore(), EditorPreferenceNames.CODEASSIST_PROPOSALS_FOREGROUND); |
| Color color = EditorUtility.getColor(rgb); |
| assistant.setProposalSelectorForeground(color); |
| } |
| } |
| } |
| } |
| |
| // update content assist preferences |
| else if (EditorPreferenceNames.CODEASSIST_PARAMETERS_BACKGROUND.equals(property)) { |
| ISourceViewer sourceViewer = getSourceViewer(); |
| if (sourceViewer != null) { |
| SourceViewerConfiguration configuration = getSourceViewerConfiguration(); |
| if (configuration != null) { |
| IContentAssistant contentAssistant = configuration.getContentAssistant(sourceViewer); |
| if (contentAssistant instanceof ContentAssistant) { |
| ContentAssistant assistant = (ContentAssistant) contentAssistant; |
| RGB rgb = PreferenceConverter.getColor(getPreferenceStore(), EditorPreferenceNames.CODEASSIST_PARAMETERS_BACKGROUND); |
| Color color = EditorUtility.getColor(rgb); |
| assistant.setContextInformationPopupBackground(color); |
| assistant.setContextSelectorBackground(color); |
| } |
| } |
| } |
| } |
| |
| // update content assist preferences |
| else if (EditorPreferenceNames.CODEASSIST_PARAMETERS_FOREGROUND.equals(property)) { |
| ISourceViewer sourceViewer = getSourceViewer(); |
| if (sourceViewer != null) { |
| SourceViewerConfiguration configuration = getSourceViewerConfiguration(); |
| if (configuration != null) { |
| IContentAssistant contentAssistant = configuration.getContentAssistant(sourceViewer); |
| if (contentAssistant instanceof ContentAssistant) { |
| ContentAssistant assistant = (ContentAssistant) contentAssistant; |
| RGB rgb = PreferenceConverter.getColor(getPreferenceStore(), EditorPreferenceNames.CODEASSIST_PARAMETERS_FOREGROUND); |
| Color color = EditorUtility.getColor(rgb); |
| assistant.setContextInformationPopupForeground(color); |
| assistant.setContextSelectorForeground(color); |
| } |
| } |
| } |
| } |
| |
| super.handlePreferenceStoreChanged(event); |
| } |
| |
| private boolean inBusyState() { |
| return fBusyState; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.IEditorPart#init(org.eclipse.ui.IEditorSite, |
| * org.eclipse.ui.IEditorInput) |
| */ |
| public void init(IEditorSite site, IEditorInput input) throws PartInitException { |
| // if we've gotten an error elsewhere, before |
| // we've actually opened, then don't open. |
| if (shouldClose) { |
| setSite(site); |
| close(false); |
| } |
| else { |
| super.init(site, input); |
| } |
| } |
| |
| /** |
| * Set the document provider for this editor. |
| * <p> |
| * Not API. May be removed in the future. |
| * </p> |
| * |
| * @param documentProvider |
| * documentProvider to initialize |
| */ |
| public void initializeDocumentProvider(IDocumentProvider documentProvider) { |
| if (documentProvider != null) { |
| setDocumentProvider(documentProvider); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.texteditor.AbstractTextEditor#initializeDragAndDrop(org.eclipse.jface.text.source.ISourceViewer) |
| */ |
| protected void initializeDragAndDrop(ISourceViewer viewer) { |
| IPreferenceStore store = getPreferenceStore(); |
| if (store != null && store.getBoolean(PREFERENCE_TEXT_DRAG_AND_DROP_ENABLED)) |
| initializeDrop(viewer); |
| } |
| |
| protected void initializeDrop(ITextViewer textViewer) { |
| int operations = DND.DROP_COPY | DND.DROP_MOVE; |
| fDropTarget = new DropTarget(textViewer.getTextWidget(), operations); |
| fDropAdapter = new ReadOnlyAwareDropTargetAdapter(true); |
| fDropAdapter.setTargetEditor(this); |
| fDropAdapter.setTargetIDs(getConfigurationPoints()); |
| fDropAdapter.setTextViewer(textViewer); |
| fDropTarget.setTransfer(fDropAdapter.getTransfers()); |
| fDropTarget.addDropListener(fDropAdapter); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#initializeEditor() |
| */ |
| protected void initializeEditor() { |
| super.initializeEditor(); |
| |
| setPreferenceStore(createCombinedPreferenceStore()); |
| |
| setRangeIndicator(new DefaultRangeIndicator()); |
| setEditorContextMenuId(EDITOR_CONTEXT_MENU_ID); |
| initializeDocumentProvider(null); |
| // set the infopop for source viewer |
| String helpId = getHelpContextId(); |
| // no infopop set or using default text editor help, use default |
| if (helpId == null || ITextEditorHelpContextIds.TEXT_EDITOR.equals(helpId)) |
| helpId = IHelpContextIds.XML_SOURCE_VIEW_HELPID; |
| setHelpContextId(helpId); |
| // defect 203158 - disable ruler context menu for |
| // beta |
| // setRulerContextMenuId(RULER_CONTEXT_MENU_ID); |
| configureInsertMode(SMART_INSERT, true); |
| |
| // enable the base source editor activity when editor opens |
| try { |
| // FIXME: - commented out to avoid minor dependancy during |
| // transition to org.eclipse |
| // WTPActivityBridge.getInstance().enableActivity(CORE_SSE_ACTIVITY_ID, |
| // true); |
| } |
| catch (Exception t) { |
| // if something goes wrong with enabling activity, just log the |
| // error but dont |
| // have it break the editor |
| Logger.log(Logger.WARNING_DEBUG, t.getMessage(), t); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.editors.text.TextEditor#initializeKeyBindingScopes() |
| */ |
| protected void initializeKeyBindingScopes() { |
| setKeyBindingScopes(new String[]{EDITOR_KEYBINDING_SCOPE_ID}); |
| } |
| |
| /** |
| * Initializes the editor's source viewer and other items that were source |
| * viewer-dependent. |
| */ |
| private void initializeSourceViewer() { |
| IAction openHyperlinkAction = getAction(StructuredTextEditorActionConstants.ACTION_NAME_OPEN_FILE); |
| if (openHyperlinkAction instanceof OpenHyperlinkAction) { |
| ((OpenHyperlinkAction) openHyperlinkAction).setHyperlinkDetectors(getSourceViewerConfiguration().getHyperlinkDetectors(getSourceViewer())); |
| } |
| |
| // do not even install projection support until folding is actually |
| // enabled |
| if (isFoldingEnabled()) { |
| installProjectionSupport(); |
| } |
| } |
| |
| protected void initSourceViewer(StructuredTextViewer sourceViewer) { |
| // ensure decoration support is configured |
| getSourceViewerDecorationSupport(sourceViewer); |
| } |
| |
| protected void installTextDragAndDrop(ISourceViewer viewer) { |
| // do nothing |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.editors.text.TextEditor#installEncodingSupport() |
| */ |
| protected void installEncodingSupport() { |
| fEncodingSupport = new EncodingSupport(getConfigurationPoints()); |
| fEncodingSupport.initialize(this); |
| } |
| |
| /** |
| * Install everything necessary to get document folding working and enable |
| * document folding |
| */ |
| private void installProjectionSupport() { |
| ProjectionViewer projectionViewer = (ProjectionViewer) getSourceViewer(); |
| |
| fProjectionSupport = new ProjectionSupport(projectionViewer, getAnnotationAccess(), getSharedColors()); |
| fProjectionSupport.addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.error"); //$NON-NLS-1$ |
| fProjectionSupport.addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.warning"); //$NON-NLS-1$ |
| fProjectionSupport.setHoverControlCreator(new IInformationControlCreator() { |
| public IInformationControl createInformationControl(Shell parent) { |
| return new DefaultInformationControl(parent); |
| } |
| }); |
| fProjectionSupport.install(); |
| |
| if (isFoldingEnabled()) |
| projectionViewer.doOperation(ProjectionViewer.TOGGLE); |
| } |
| |
| /** |
| * Return whether document folding should be enabled according to the |
| * preference store settings. |
| * |
| * @return <code>true</code> if document folding should be enabled |
| */ |
| private boolean isFoldingEnabled() { |
| IPreferenceStore store = getPreferenceStore(); |
| // check both preference store and vm argument |
| return (store.getBoolean(AbstractStructuredFoldingStrategy.FOLDING_ENABLED)); |
| } |
| |
| /** |
| * Determine if the user preference for as you type validation is enabled or not |
| */ |
| private boolean isValidationEnabled() { |
| return getPreferenceStore().getBoolean(CommonEditorPreferenceNames.EVALUATE_TEMPORARY_PROBLEMS); |
| } |
| |
| /** |
| * <p>Logs a warning about how this {@link StructuredTextEditor} just opened an {@link IEditorInput} |
| * it was not designed to open.</p> |
| * |
| * @param input the {@link IEditorInput} this {@link StructuredTextEditor} was not designed to open |
| * to log the message about. |
| */ |
| private void logUnexpectedDocumentKind(IEditorInput input) { |
| Logger.log(Logger.WARNING, "StructuredTextEditor being used without StructuredDocument"); //$NON-NLS-1$ |
| String name = null; |
| if (input != null) { |
| name = input.getName(); |
| } |
| else { |
| name = "input was null"; //$NON-NLS-1$ |
| } |
| Logger.log(Logger.WARNING, " Input Name: " + name); //$NON-NLS-1$ |
| String implClass = null; |
| IDocument document = getDocumentProvider().getDocument(input); |
| if (document != null) { |
| implClass = document.getClass().getName(); |
| } |
| else { |
| implClass = "document was null"; //$NON-NLS-1$ |
| } |
| Logger.log(Logger.WARNING, " Unexpected IDocumentProvider implementation: " + getDocumentProvider().getClass().getName()); //$NON-NLS-1$ |
| Logger.log(Logger.WARNING, " Unexpected IDocument implementation: " + implClass); //$NON-NLS-1$ |
| } |
| |
| /* |
| * @see org.eclipse.ui.texteditor.AbstractTextEditor#performRevert() |
| */ |
| protected void performRevert() { |
| ProjectionViewer projectionViewer = (ProjectionViewer) getSourceViewer(); |
| projectionViewer.setRedraw(false); |
| try { |
| |
| boolean projectionMode = projectionViewer.isProjectionMode(); |
| if (projectionMode) { |
| projectionViewer.disableProjection(); |
| } |
| |
| super.performRevert(); |
| |
| if (projectionMode) { |
| projectionViewer.enableProjection(); |
| } |
| |
| } |
| finally { |
| projectionViewer.setRedraw(true); |
| } |
| } |
| |
| /** |
| * {@inheritDoc} |
| * <p> |
| * Not API. May be reduced to protected method in the future. |
| * </p> |
| */ |
| public void rememberSelection() { |
| /* |
| * This method was made public for use by editors that use |
| * StructuredTextEditor (like some clients) |
| */ |
| super.rememberSelection(); |
| } |
| |
| |
| /** |
| * both starts and resets the busy state timer |
| */ |
| private void resetBusyState() { |
| // reset the "busy" timeout |
| if (fBusyTimer != null) { |
| fBusyTimer.cancel(); |
| } |
| startBusyTimer(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| * <p> |
| * Not API. May be reduced to protected method in the future. |
| * </p> |
| */ |
| public void restoreSelection() { |
| /* |
| * This method was made public for use by editors that use |
| * StructuredTextEditor (like some clients) |
| */ |
| // catch odd case where source viewer has no text |
| // widget (defect |
| // 227670) |
| if ((getSourceViewer() != null) && (getSourceViewer().getTextWidget() != null)) |
| super.restoreSelection(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.texteditor.AbstractTextEditor#rulerContextMenuAboutToShow(org.eclipse.jface.action.IMenuManager) |
| */ |
| protected void rulerContextMenuAboutToShow(IMenuManager menu) { |
| super.rulerContextMenuAboutToShow(menu); |
| |
| IMenuManager foldingMenu = new MenuManager(SSEUIMessages.Folding, "projection"); //$NON-NLS-1$ |
| menu.appendToGroup(ITextEditorActionConstants.GROUP_RULERS, foldingMenu); |
| |
| IAction action = getAction("FoldingToggle"); //$NON-NLS-1$ |
| foldingMenu.add(action); |
| action = getAction("FoldingExpandAll"); //$NON-NLS-1$ |
| foldingMenu.add(action); |
| action = getAction("FoldingCollapseAll"); //$NON-NLS-1$ |
| foldingMenu.add(action); |
| |
| IStructuredModel internalModel = getInternalModel(); |
| if (internalModel != null) { |
| boolean debuggingAvailable = BreakpointProviderBuilder.getInstance().isAvailable(internalModel.getContentTypeIdentifier(), BreakpointRulerAction.getFileExtension(getEditorInput())); |
| if (debuggingAvailable) { |
| // append actions to "debug" group (created in |
| // AbstractDecoratedTextEditor.rulerContextMenuAboutToShow(IMenuManager) |
| menu.appendToGroup("debug", getAction(ActionDefinitionIds.TOGGLE_BREAKPOINTS)); //$NON-NLS-1$ |
| menu.appendToGroup("debug", getAction(ActionDefinitionIds.MANAGE_BREAKPOINTS)); //$NON-NLS-1$ |
| menu.appendToGroup("debug", getAction(ActionDefinitionIds.EDIT_BREAKPOINTS)); //$NON-NLS-1$ |
| } |
| addExtendedRulerContextMenuActions(menu); |
| } |
| } |
| |
| /** |
| * {@inheritDoc} |
| * <p> |
| * Overridden to expose part activation handling for multi-page editors. |
| * </p> |
| * <p> |
| * Not API. May be reduced to protected method in the future. |
| * </p> |
| * |
| * @see org.eclipse.ui.texteditor.AbstractTextEditor#safelySanityCheckState(org.eclipse.ui.IEditorInput) |
| */ |
| public void safelySanityCheckState(IEditorInput input) { |
| super.safelySanityCheckState(input); |
| } |
| |
| protected void sanityCheckState(IEditorInput input) { |
| try { |
| ++validateEditCount; |
| super.sanityCheckState(input); |
| } |
| finally { |
| --validateEditCount; |
| } |
| } |
| |
| private void savedModel(IStructuredModel model) { |
| if (model != null) { |
| model.changedModel(); |
| } |
| } |
| |
| /** |
| * Ensure that the correct IDocumentProvider is used. For direct models, a |
| * special provider is used. For StorageEditorInputs, use a custom |
| * provider that creates a usable ResourceAnnotationModel. For everything |
| * else, use the base support. |
| * |
| * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#setDocumentProvider(org.eclipse.ui.IEditorInput) |
| */ |
| protected void setDocumentProvider(IEditorInput input) { |
| if (input instanceof IStructuredModel) { |
| // largely untested |
| setDocumentProvider(StructuredModelDocumentProvider.getInstance()); |
| } |
| else if (input instanceof IStorageEditorInput && !(input instanceof IFileEditorInput)) { |
| setDocumentProvider(StorageModelProvider.getInstance()); |
| } |
| else { |
| super.setDocumentProvider(input); |
| } |
| } |
| |
| /** |
| * Set editor part associated with this editor. |
| * <p> |
| * Not API. May be removed in the future. |
| * </p> |
| * |
| * @param editorPart |
| * editor part associated with this editor |
| */ |
| public void setEditorPart(IEditorPart editorPart) { |
| fEditorPart = editorPart; |
| } |
| |
| /** |
| * Sets the model field within this editor. |
| * |
| * @deprecated - can eventually be eliminated |
| */ |
| private void setModel(IStructuredModel newModel) { |
| Assert.isNotNull(getDocumentProvider(), "document provider can not be null when setting model"); //$NON-NLS-1$ |
| if (fStructuredModel != null) { |
| fStructuredModel.removeModelStateListener(getInternalModelStateListener()); |
| } |
| fStructuredModel = newModel; |
| if (fStructuredModel != null) { |
| fStructuredModel.addModelStateListener(getInternalModelStateListener()); |
| } |
| // update() should be called whenever the model is |
| // set or changed |
| update(); |
| } |
| |
| /** |
| * Sets the editor's source viewer configuration which it uses to |
| * configure it's internal source viewer. This method was overwritten so |
| * that viewer configuration could be set after editor part was created. |
| */ |
| protected void setSourceViewerConfiguration(SourceViewerConfiguration config) { |
| SourceViewerConfiguration oldSourceViewerConfiguration = getSourceViewerConfiguration(); |
| super.setSourceViewerConfiguration(config); |
| StructuredTextViewer stv = getTextViewer(); |
| if (stv != null) { |
| /* |
| * There should be no need to unconfigure before configure because |
| * configure will also unconfigure before configuring |
| */ |
| removeReconcilingListeners(oldSourceViewerConfiguration, stv); |
| stv.unconfigure(); |
| setStatusLineMessage(null); |
| stv.configure(config); |
| addReconcilingListeners(config, stv); |
| } |
| } |
| |
| private void removeReconcilingListeners(SourceViewerConfiguration config, StructuredTextViewer stv) { |
| IReconciler reconciler = config.getReconciler(stv); |
| if (reconciler instanceof DocumentRegionProcessor) { |
| for (int i = 0; i < fReconcilingListeners.length; i++) { |
| ((DocumentRegionProcessor) reconciler).removeReconcilingListener(fReconcilingListeners[i]); |
| } |
| } |
| } |
| |
| private void addReconcilingListeners(SourceViewerConfiguration config, StructuredTextViewer stv) { |
| try { |
| List reconcilingListeners = new ArrayList(fReconcilingListeners.length); |
| String[] ids = getConfigurationPoints(); |
| for (int i = 0; i < ids.length; i++) { |
| reconcilingListeners.addAll(ExtendedConfigurationBuilder.getInstance().getConfigurations("sourceReconcilingListener", ids[i])); //$NON-NLS-1$ |
| } |
| fReconcilingListeners = (ISourceReconcilingListener[]) reconcilingListeners.toArray(new ISourceReconcilingListener[reconcilingListeners.size()]); |
| } |
| catch (ClassCastException e) { |
| Logger.log(Logger.ERROR, "Configuration has a reconciling listener that does not implement ISourceReconcilingListener."); //$NON-NLS-1$ |
| } |
| |
| IReconciler reconciler = config.getReconciler(stv); |
| if (reconciler instanceof DocumentRegionProcessor) { |
| for (int i = 0; i < fReconcilingListeners.length; i++) |
| ((DocumentRegionProcessor) reconciler).addReconcilingListener(fReconcilingListeners[i]); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.part.WorkbenchPart#showBusy(boolean) |
| */ |
| public void showBusy(boolean busy) { |
| // no-op |
| super.showBusy(busy); |
| } |
| |
| private void startBusyTimer() { |
| // TODO: we need a resettable timer, so not so |
| // many are created |
| fBusyTimer = new Timer(true); |
| fBusyTimer.schedule(new TimeOutExpired(), BUSY_STATE_DELAY); |
| } |
| |
| protected void uninstallTextDragAndDrop(ISourceViewer viewer) { |
| // do nothing |
| } |
| |
| /** |
| * Update should be called whenever the model is set or changed (as in |
| * swapped) |
| * <p> |
| * Not API. May be removed in the future. |
| * </p> |
| */ |
| public void update() { |
| if (fOutlinePage != null && fOutlinePage instanceof ConfigurableContentOutlinePage) { |
| ContentOutlineConfiguration cfg = createContentOutlineConfiguration(); |
| ((ConfigurableContentOutlinePage) fOutlinePage).setConfiguration(cfg); |
| IStructuredModel internalModel = getInternalModel(); |
| ((ConfigurableContentOutlinePage) fOutlinePage).setInputContentTypeIdentifier(internalModel.getContentTypeIdentifier()); |
| ((ConfigurableContentOutlinePage) fOutlinePage).setInput(internalModel); |
| } |
| if (fPropertySheetPage != null && fPropertySheetPage instanceof ConfigurablePropertySheetPage) { |
| PropertySheetConfiguration cfg = createPropertySheetConfiguration(); |
| ((ConfigurablePropertySheetPage) fPropertySheetPage).setConfiguration(cfg); |
| } |
| disposeModelDependentFields(); |
| |
| fShowInTargetIds = createShowInTargetIds(); |
| |
| if (getSourceViewerConfiguration() instanceof StructuredTextViewerConfiguration && fStatusLineLabelProvider != null) { |
| fStatusLineLabelProvider.dispose(); |
| } |
| |
| String configurationId = fViewerConfigurationTargetId; |
| updateSourceViewerConfiguration(); |
| |
| /* Only reinstall if the configuration id has changed */ |
| if (configurationId != null && !configurationId.equals(fViewerConfigurationTargetId)) { |
| uninstallSemanticHighlighting(); |
| installSemanticHighlighting(); |
| } |
| |
| if (getSourceViewerConfiguration() instanceof StructuredTextViewerConfiguration) { |
| fStatusLineLabelProvider = ((StructuredTextViewerConfiguration) getSourceViewerConfiguration()).getStatusLineLabelProvider(getSourceViewer()); |
| updateStatusLine(null); |
| } |
| |
| if (fEncodingSupport != null && fEncodingSupport instanceof EncodingSupport) { |
| ((EncodingSupport) fEncodingSupport).reinitialize(getConfigurationPoints()); |
| } |
| |
| createModelDependentFields(); |
| } |
| |
| /** |
| * Updates all content dependent actions. |
| */ |
| protected void updateContentDependentActions() { |
| super.updateContentDependentActions(); |
| // super.updateContentDependentActions only updates |
| // the enable/disable |
| // state of all |
| // the content dependent actions. |
| // StructuredTextEditor's undo and redo actions |
| // have a detail label and |
| // description. |
| // They needed to be updated. |
| if (!fEditorDisposed) |
| updateMenuText(); |
| } |
| |
| |
| /** |
| * Updates the editor context menu by creating a new context menu with the |
| * given menu id |
| * |
| * @param contextMenuId |
| * Cannot be null |
| */ |
| private void updateEditorContextMenuId(String contextMenuId) { |
| // update editor context menu id if updating to a new id or if context |
| // menu is not already set up |
| if (!contextMenuId.equals(getEditorContextMenuId()) || (fTextContextMenu == null)) { |
| setEditorContextMenuId(contextMenuId); |
| |
| if (getSourceViewer() != null) { |
| StyledText styledText = getSourceViewer().getTextWidget(); |
| if (styledText != null) { |
| // dispose of previous context menu |
| if (fTextContextMenu != null) { |
| fTextContextMenu.dispose(); |
| } |
| if (fTextContextMenuManager != null) { |
| fTextContextMenuManager.removeMenuListener(getContextMenuListener()); |
| fTextContextMenuManager.removeAll(); |
| fTextContextMenuManager.dispose(); |
| } |
| |
| fTextContextMenuManager = new MenuManager(getEditorContextMenuId(), getEditorContextMenuId()); |
| fTextContextMenuManager.setRemoveAllWhenShown(true); |
| fTextContextMenuManager.addMenuListener(getContextMenuListener()); |
| |
| fTextContextMenu = fTextContextMenuManager.createContextMenu(styledText); |
| styledText.setMenu(fTextContextMenu); |
| |
| getSite().registerContextMenu(getEditorContextMenuId(), fTextContextMenuManager, getSelectionProvider()); |
| |
| // also register this menu for source page part and |
| // structured text editor ids |
| String partId = getSite().getId(); |
| if (partId != null) { |
| getSite().registerContextMenu(partId + EDITOR_CONTEXT_MENU_SUFFIX, fTextContextMenuManager, getSelectionProvider()); |
| } |
| getSite().registerContextMenu(EDITOR_CONTEXT_MENU_ID, fTextContextMenuManager, getSelectionProvider()); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Updates editor context menu, vertical ruler menu, help context id for |
| * new content type |
| * |
| * @param contentType |
| */ |
| private void updateEditorControlsForContentType(String contentType) { |
| if (contentType == null) { |
| updateEditorContextMenuId(EDITOR_CONTEXT_MENU_ID); |
| updateRulerContextMenuId(RULER_CONTEXT_MENU_ID); |
| updateHelpContextId(ITextEditorHelpContextIds.TEXT_EDITOR); |
| } |
| else { |
| updateEditorContextMenuId(contentType + EDITOR_CONTEXT_MENU_SUFFIX); |
| updateRulerContextMenuId(contentType + RULER_CONTEXT_MENU_SUFFIX); |
| updateHelpContextId(contentType + "_source_HelpId"); //$NON-NLS-1$ |
| |
| /* Activate the contexts defined for this editor */ |
| activateContexts((IContextService) getSite().getService(IContextService.class)); |
| } |
| } |
| |
| private void updateEncodingMemento() { |
| boolean failed = false; |
| IStructuredModel internalModel = getInternalModel(); |
| if (internalModel != null) { |
| IStructuredDocument doc = internalModel.getStructuredDocument(); |
| EncodingMemento memento = doc.getEncodingMemento(); |
| IDocumentCharsetDetector detector = internalModel.getModelHandler().getEncodingDetector(); |
| if (memento != null && detector != null) { |
| detector.set(doc); |
| try { |
| String newEncoding = detector.getEncoding(); |
| if (newEncoding != null) { |
| memento.setDetectedCharsetName(newEncoding); |
| } |
| } |
| catch (IOException e) { |
| failed = true; |
| } |
| } |
| /** |
| * Be sure to use the new value but only if no exception |
| * occurred. (we may find cases we need to do more error recovery |
| * there) should be near impossible to get IOException from |
| * processing the _document_ |
| */ |
| if (!failed) { |
| doc.setEncodingMemento(memento); |
| } |
| } |
| } |
| |
| /** |
| * Updates the help context of the editor with the given help context id |
| * |
| * @param helpContextId |
| * Cannot be null |
| */ |
| private void updateHelpContextId(String helpContextId) { |
| if (!helpContextId.equals(getHelpContextId())) { |
| setHelpContextId(helpContextId); |
| |
| if (getSourceViewer() != null) { |
| StyledText styledText = getSourceViewer().getTextWidget(); |
| if (styledText != null) { |
| IWorkbenchHelpSystem helpSystem = PlatformUI.getWorkbench().getHelpSystem(); |
| helpSystem.setHelp(styledText, getHelpContextId()); |
| } |
| } |
| } |
| } |
| |
| /* |
| * Update the hovering behavior depending on the preferences. |
| */ |
| private void updateHoverBehavior() { |
| SourceViewerConfiguration configuration = getSourceViewerConfiguration(); |
| String[] types = configuration.getConfiguredContentTypes(getSourceViewer()); |
| |
| for (int i = 0; i < types.length; i++) { |
| |
| String t = types[i]; |
| |
| ISourceViewer sourceViewer = getSourceViewer(); |
| if (sourceViewer instanceof ITextViewerExtension2) { |
| // Remove existing hovers |
| ((ITextViewerExtension2) sourceViewer).removeTextHovers(t); |
| |
| int[] stateMasks = configuration.getConfiguredTextHoverStateMasks(getSourceViewer(), t); |
| |
| if (stateMasks != null) { |
| for (int j = 0; j < stateMasks.length; j++) { |
| int stateMask = stateMasks[j]; |
| ITextHover textHover = configuration.getTextHover(sourceViewer, t, stateMask); |
| ((ITextViewerExtension2) sourceViewer).setTextHover(textHover, t, stateMask); |
| } |
| } |
| else { |
| ITextHover textHover = configuration.getTextHover(sourceViewer, t); |
| ((ITextViewerExtension2) sourceViewer).setTextHover(textHover, t, ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK); |
| } |
| } |
| else |
| sourceViewer.setTextHover(configuration.getTextHover(sourceViewer, t), t); |
| } |
| } |
| |
| private void updateMenuText() { |
| ITextViewer viewer = getTextViewer(); |
| StyledText widget = null; |
| if (viewer != null) |
| widget = viewer.getTextWidget(); |
| |
| if (fStructuredModel != null && !fStructuredModel.isModelStateChanging() && viewer != null && widget != null && !widget.isDisposed()) { |
| // performance: don't force an update of the action bars unless |
| // required as it is expensive |
| String previousUndoText = null; |
| String previousUndoDesc = null; |
| String previousRedoText = null; |
| String previousRedoDesc = null; |
| boolean updateActions = false; |
| IAction undoAction = getAction(ITextEditorActionConstants.UNDO); |
| IAction redoAction = getAction(ITextEditorActionConstants.REDO); |
| if (undoAction != null) { |
| previousUndoText = undoAction.getText(); |
| previousUndoDesc = undoAction.getDescription(); |
| updateActions = updateActions || previousUndoText == null || previousUndoDesc == null; |
| undoAction.setText(UNDO_ACTION_TEXT_DEFAULT); |
| undoAction.setDescription(UNDO_ACTION_DESC_DEFAULT); |
| } |
| if (redoAction != null) { |
| previousRedoText = redoAction.getText(); |
| previousRedoDesc = redoAction.getDescription(); |
| updateActions = updateActions || previousRedoText == null || previousRedoDesc == null; |
| redoAction.setText(REDO_ACTION_TEXT_DEFAULT); |
| redoAction.setDescription(REDO_ACTION_DESC_DEFAULT); |
| } |
| if (fStructuredModel.getUndoManager() != null) { |
| IStructuredTextUndoManager undoManager = fStructuredModel.getUndoManager(); |
| // get undo command |
| Command undoCommand = undoManager.getUndoCommand(); |
| // set undo label and description |
| if (undoAction != null) { |
| undoAction.setEnabled(undoManager.undoable()); |
| if (undoCommand != null) { |
| String label = undoCommand.getLabel(); |
| if (label != null) { |
| String customText = MessageFormat.format(UNDO_ACTION_TEXT, new String[]{label}); |
| updateActions = updateActions || customText == null || previousUndoText == null || !customText.equals(previousUndoText); |
| undoAction.setText(customText); |
| } |
| String desc = undoCommand.getDescription(); |
| if (desc != null) { |
| String customDesc = MessageFormat.format(UNDO_ACTION_DESC, new String[]{desc}); |
| updateActions = updateActions || customDesc == null || previousRedoDesc == null || !customDesc.equals(previousUndoDesc); |
| undoAction.setDescription(customDesc); |
| } |
| } |
| } |
| // get redo command |
| Command redoCommand = undoManager.getRedoCommand(); |
| // set redo label and description |
| if (redoAction != null) { |
| redoAction.setEnabled(undoManager.redoable()); |
| if (redoCommand != null) { |
| String label = redoCommand.getLabel(); |
| if (label != null) { |
| String customText = MessageFormat.format(REDO_ACTION_TEXT, new String[]{label}); |
| updateActions = updateActions || customText == null || previousRedoText == null || !customText.equals(previousRedoText); |
| redoAction.setText(customText); |
| } |
| String desc = redoCommand.getDescription(); |
| if (desc != null) { |
| String customDesc = MessageFormat.format(REDO_ACTION_DESC, new String[]{desc}); |
| updateActions = updateActions || customDesc == null || previousRedoDesc == null || !customDesc.equals(previousRedoDesc); |
| redoAction.setDescription(customDesc); |
| } |
| } |
| } |
| } |
| // tell the action bars to update |
| if (updateActions) { |
| if (getEditorSite().getActionBars() != null) { |
| getEditorSite().getActionBars().updateActionBars(); |
| } |
| else if (getEditorPart() != null && getEditorPart().getEditorSite().getActionBars() != null) { |
| getEditorPart().getEditorSite().getActionBars().updateActionBars(); |
| } |
| } |
| } |
| } |
| |
| void updateRangeIndication(ISelection selection) { |
| boolean rangeUpdated = false; |
| if (selection instanceof IStructuredSelection && !((IStructuredSelection) selection).isEmpty()) { |
| Object[] objects = ((IStructuredSelection) selection).toArray(); |
| if (objects.length > 0 && objects[0] instanceof IndexedRegion) { |
| int start = ((IndexedRegion) objects[0]).getStartOffset(); |
| int end = ((IndexedRegion) objects[0]).getEndOffset(); |
| if (objects.length > 1) { |
| for (int i = 1; i < objects.length; i++) { |
| start = Math.min(start, ((IndexedRegion) objects[i]).getStartOffset()); |
| end = Math.max(end, ((IndexedRegion) objects[i]).getEndOffset()); |
| } |
| } |
| getSourceViewer().setRangeIndication(start, end - start, false); |
| rangeUpdated = true; |
| } |
| } |
| if (!rangeUpdated && getSourceViewer() != null) { |
| if (selection instanceof ITextSelection) { |
| getSourceViewer().setRangeIndication(((ITextSelection) selection).getOffset(), ((ITextSelection) selection).getLength(), false); |
| } |
| else { |
| getSourceViewer().removeRangeIndication(); |
| } |
| } |
| } |
| |
| |
| /** |
| * Updates the editor vertical ruler menu by creating a new vertical ruler |
| * context menu with the given menu id |
| * |
| * @param rulerMenuId |
| * Cannot be null |
| */ |
| private void updateRulerContextMenuId(String rulerMenuId) { |
| // update ruler context menu id if updating to a new id or if context |
| // menu is not already set up |
| if (!rulerMenuId.equals(getRulerContextMenuId()) || (fRulerContextMenu == null)) { |
| setRulerContextMenuId(rulerMenuId); |
| |
| if (getVerticalRuler() != null) { |
| // dispose of previous ruler context menu |
| if (fRulerContextMenu != null) { |
| fRulerContextMenu.dispose(); |
| } |
| if (fRulerContextMenuManager != null) { |
| fRulerContextMenuManager.removeMenuListener(getContextMenuListener()); |
| fRulerContextMenuManager.removeAll(); |
| fRulerContextMenuManager.dispose(); |
| } |
| |
| fRulerContextMenuManager = new MenuManager(getRulerContextMenuId(), getRulerContextMenuId()); |
| fRulerContextMenuManager.setRemoveAllWhenShown(true); |
| fRulerContextMenuManager.addMenuListener(getContextMenuListener()); |
| |
| Control rulerControl = getVerticalRuler().getControl(); |
| fRulerContextMenu = fRulerContextMenuManager.createContextMenu(rulerControl); |
| rulerControl.setMenu(fRulerContextMenu); |
| |
| getSite().registerContextMenu(getRulerContextMenuId(), fRulerContextMenuManager, getSelectionProvider()); |
| |
| // also register this menu for source page part and structured |
| // text editor ids |
| String partId = getSite().getId(); |
| if (partId != null) { |
| getSite().registerContextMenu(partId + RULER_CONTEXT_MENU_SUFFIX, fRulerContextMenuManager, getSelectionProvider()); |
| } |
| getSite().registerContextMenu(RULER_CONTEXT_MENU_ID, fRulerContextMenuManager, getSelectionProvider()); |
| } |
| } |
| } |
| |
| private void updateSourceViewerConfiguration() { |
| SourceViewerConfiguration configuration = getSourceViewerConfiguration(); |
| // no need to update source viewer configuration if one does not exist |
| // yet |
| if (configuration == null) { |
| return; |
| } |
| // do not configure source viewer configuration twice |
| boolean configured = false; |
| |
| // structuredtextviewer only works with |
| // structuredtextviewerconfiguration |
| if (!(configuration instanceof StructuredTextViewerConfiguration)) { |
| ConfigurationAndTarget cat = createSourceViewerConfiguration(); |
| fViewerConfigurationTargetId = cat.getTargetId(); |
| configuration = cat.getConfiguration(); |
| setSourceViewerConfiguration(configuration); |
| configured = true; |
| } |
| else { |
| ConfigurationAndTarget cat = createSourceViewerConfiguration(); |
| StructuredTextViewerConfiguration newViewerConfiguration = cat.getConfiguration(); |
| if (!(cat.getTargetId().equals(fViewerConfigurationTargetId))) { |
| // d282894 use newViewerConfiguration |
| fViewerConfigurationTargetId = cat.getTargetId(); |
| configuration = newViewerConfiguration; |
| setSourceViewerConfiguration(configuration); |
| configured = true; |
| } |
| } |
| |
| if (getSourceViewer() != null) { |
| // not sure if really need to reconfigure when input changes |
| // (maybe only need to reset viewerconfig's document) |
| if (!configured) |
| getSourceViewer().configure(configuration); |
| IAction openHyperlinkAction = getAction(StructuredTextEditorActionConstants.ACTION_NAME_OPEN_FILE); |
| if (openHyperlinkAction instanceof OpenHyperlinkAction) { |
| ((OpenHyperlinkAction) openHyperlinkAction).setHyperlinkDetectors(getSourceViewerConfiguration().getHyperlinkDetectors(getSourceViewer())); |
| } |
| } |
| } |
| |
| protected void updateStatusField(String category) { |
| super.updateStatusField(category); |
| |
| if (category == null) |
| return; |
| |
| if (StructuredTextEditorActionConstants.STATUS_CATEGORY_OFFSET.equals(category)) { |
| IStatusField field = getStatusField(category); |
| ISourceViewer sourceViewer = getSourceViewer(); |
| if (field != null && sourceViewer != null) { |
| Point selection = sourceViewer.getTextWidget().getSelection(); |
| int offset1 = widgetOffset2ModelOffset(sourceViewer, selection.x); |
| int offset2 = widgetOffset2ModelOffset(sourceViewer, selection.y); |
| String text = null; |
| if (offset1 != offset2) |
| text = "[" + offset1 + "-" + offset2 + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| else |
| text = "[ " + offset1 + " ]"; //$NON-NLS-1$ //$NON-NLS-2$ |
| field.setText(text == null ? fErrorLabel : text); |
| } |
| } |
| } |
| |
| public Annotation gotoAnnotation(boolean forward) { |
| Annotation result = super.gotoAnnotation(forward); |
| if(result != null) |
| fSelectionChangedFromGoto = true; |
| return result; |
| } |
| |
| void updateStatusLine(ISelection selection) { |
| // Bug 210481 - Don't update the status line if the selection |
| // was caused by go to navigation |
| if(fSelectionChangedFromGoto) { |
| fSelectionChangedFromGoto = false; |
| return; |
| } |
| IStatusLineManager statusLineManager = getEditorSite().getActionBars().getStatusLineManager(); |
| if (fStatusLineLabelProvider != null && statusLineManager != null) { |
| String text = null; |
| Image image = null; |
| if (selection instanceof IStructuredSelection && !selection.isEmpty()) { |
| Object firstElement = ((IStructuredSelection) selection).getFirstElement(); |
| if (firstElement != null) { |
| text = fStatusLineLabelProvider.getText(firstElement); |
| image = fStatusLineLabelProvider.getImage((firstElement)); |
| } |
| } |
| if (image == null) { |
| statusLineManager.setMessage(text); |
| } |
| else { |
| statusLineManager.setMessage(image, text); |
| } |
| } |
| } |
| |
| /** |
| * Returns the signed current selection. |
| * The length will be negative if the resulting selection |
| * is right-to-left (RtoL). |
| * <p> |
| * The selection offset is model based. |
| * </p> |
| * |
| * @param sourceViewer the source viewer |
| * @return a region denoting the current signed selection, for a resulting RtoL selections length is < 0 |
| */ |
| IRegion getSignedSelection(ISourceViewer sourceViewer) { |
| StyledText text= sourceViewer.getTextWidget(); |
| Point selection= text.getSelectionRange(); |
| |
| if (text.getCaretOffset() == selection.x) { |
| selection.x= selection.x + selection.y; |
| selection.y= -selection.y; |
| } |
| |
| selection.x= widgetOffset2ModelOffset(sourceViewer, selection.x); |
| |
| return new Region(selection.x, selection.y); |
| } |
| |
| protected SourceViewerDecorationSupport getSourceViewerDecorationSupport(ISourceViewer viewer) { |
| /* Removed workaround for Bug [206913] source annotations are not painting in source editors. |
| * With the new presentation reconciler, we no longer need to force the painting. This |
| * actually caused Bug [219776] Wrong annotation display on macs. We forced the |
| * Squiggles strategy, even when the native problem underline was specified for annotations */ |
| return super.getSourceViewerDecorationSupport(viewer); |
| } |
| |
| private void installCharacterPairing() { |
| IStructuredModel model = getInternalModel(); |
| if (model != null) { |
| IConfigurationElement[] elements = Platform.getExtensionRegistry().getConfigurationElementsFor(SSEUIPlugin.ID, "characterPairing"); //$NON-NLS-1$ |
| IContentTypeManager mgr = Platform.getContentTypeManager(); |
| IContentType type = mgr.getContentType(model.getContentTypeIdentifier()); |
| if (type != null) { |
| for (int i = 0; i < elements.length; i++) { |
| // Create the inserter |
| IConfigurationElement element = elements[i]; |
| try { |
| IConfigurationElement[] contentTypes = element.getChildren("contentTypeIdentifier"); |
| for (int j = 0; j < contentTypes.length; j++) { |
| String id = contentTypes[j].getAttribute("id"); |
| if (id != null) { |
| IContentType targetType = mgr.getContentType(id); |
| int priority = calculatePriority(type, targetType, 0); |
| if (priority >= 0) { |
| final CharacterPairing pairing = new CharacterPairing(); |
| pairing.priority = priority; |
| String[] partitions = StringUtils.unpack(contentTypes[j].getAttribute("partitions")); |
| pairing.partitions = new HashSet(partitions.length); |
| // Only add the inserter if there is at least one partition for the content type |
| for (int k = 0; k < partitions.length; k++) { |
| pairing.partitions.add(partitions[k]); |
| } |
| |
| pairing.inserter = (AbstractCharacterPairInserter) element.createExecutableExtension("class"); |
| if (pairing.inserter != null && partitions.length > 0) { |
| fPairInserter.addInserter(pairing); |
| /* use a SafeRunner since this method is also invoked during Part creation */ |
| SafeRunner.run(new ISafeRunnable() { |
| public void run() throws Exception { |
| pairing.inserter.initialize(); |
| } |
| |
| public void handleException(Throwable exception) { |
| // rely on default logging |
| } |
| }); |
| } |
| } |
| } |
| } |
| } catch (CoreException e) { |
| Logger.logException(e); |
| } |
| } |
| fPairInserter.prioritize(); |
| } |
| } |
| } |
| |
| /** |
| * Calculates the priority of the target content type. The closer <code>targetType</code> |
| * is to <code>type</code> the higher its priority. |
| * |
| * @param type |
| * @param targetType |
| * @param priority |
| * @return |
| */ |
| private int calculatePriority(IContentType type, IContentType targetType, int priority) { |
| if (type == null || targetType == null) |
| return -1; |
| if (type.getId().equals(targetType.getId())) |
| return priority; |
| return calculatePriority(type.getBaseType(), targetType, ++priority); |
| } |
| |
| /** |
| * Installs semantic highlighting on the editor |
| */ |
| private void installSemanticHighlighting() { |
| IStructuredModel model = getInternalModel(); |
| if (fSemanticManager == null && model != null) { |
| fSemanticManager = new SemanticHighlightingManager(); |
| fSemanticManager.install(getSourceViewer(), getPreferenceStore(), getSourceViewerConfiguration(), model.getContentTypeIdentifier()); |
| } |
| } |
| |
| /** |
| * Uninstalls semantic highlighting on the editor and performs cleanup |
| */ |
| private void uninstallSemanticHighlighting() { |
| if (fSemanticManager != null) { |
| fSemanticManager.uninstall(); |
| fSemanticManager = null; |
| } |
| } |
| |
| private IInformationPresenter configureOutlinePresenter(ISourceViewer sourceViewer, SourceViewerConfiguration config) { |
| InformationPresenter presenter = null; |
| |
| // Get the quick outline configuration |
| AbstractQuickOutlineConfiguration cfg = null; |
| ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance(); |
| String[] ids = getConfigurationPoints(); |
| for (int i = 0; cfg == null && i < ids.length; i++) { |
| cfg = (AbstractQuickOutlineConfiguration) builder.getConfiguration(ExtendedConfigurationBuilder.QUICKOUTLINECONFIGURATION, ids[i]); |
| } |
| |
| if (cfg != null) { |
| presenter = new InformationPresenter(getOutlinePresenterControlCreator(cfg)); |
| presenter.setDocumentPartitioning(config.getConfiguredDocumentPartitioning(sourceViewer)); |
| presenter.setAnchor(AbstractInformationControlManager.ANCHOR_GLOBAL); |
| IInformationProvider provider = new SourceInfoProvider(this); |
| String[] contentTypes = config.getConfiguredContentTypes(sourceViewer); |
| for (int i = 0; i < contentTypes.length; i++) { |
| presenter.setInformationProvider(provider, contentTypes[i]); |
| } |
| presenter.setSizeConstraints(50, 20, true, false); |
| } |
| return presenter; |
| } |
| |
| /** |
| * Returns the outline presenter control creator. The creator is a |
| * factory creating outline presenter controls for the given source viewer. |
| * |
| * @param sourceViewer the source viewer to be configured by this configuration |
| * @return an information control creator |
| */ |
| private IInformationControlCreator getOutlinePresenterControlCreator(final AbstractQuickOutlineConfiguration config) { |
| return new IInformationControlCreator() { |
| public IInformationControl createInformationControl(Shell parent) { |
| int shellStyle = SWT.RESIZE; |
| return new QuickOutlinePopupDialog(parent, shellStyle, getInternalModel(), config); |
| } |
| }; |
| } |
| } |