[129906] [editor] StructuredTextEditor does not throw SelectionChanged event when contents of active document is replaced by builder.
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredTextEditor.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredTextEditor.java index db9e5a5..2e1199d 100644 --- a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredTextEditor.java +++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredTextEditor.java
@@ -74,6 +74,7 @@ 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; @@ -200,6 +201,7 @@ 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; @@ -2371,6 +2373,26 @@ 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) *
diff --git a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/StructuredRegionProcessor.java b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/StructuredRegionProcessor.java index 7861f66..03b2dde 100644 --- a/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/StructuredRegionProcessor.java +++ b/bundles/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/StructuredRegionProcessor.java
@@ -31,7 +31,6 @@ * */ public class StructuredRegionProcessor extends DocumentRegionProcessor { - class ModelLifecycleListener implements IModelLifecycleListener { IStructuredModel changing = null; /** @@ -88,6 +87,9 @@ private IModelLifecycleListener fLifeCycleListener = new ModelLifecycleListener(); /** Used to get the current model on demand so a model does not need to be held by permanently */ private IDocument fCurrentDoc = null; + + /** Only to be used for content type and IModelLifecycleListener registration. All other uses should "get" the model. */ + private IStructuredModel fCurrentModel = null; /* * (non-Javadoc) @@ -194,6 +196,14 @@ * use that. */ protected String getContentType(IDocument doc) { + if (fCurrentModel != null && doc == fCurrentModel.getStructuredDocument()) { + /* + * Avoid "get"ting a model if we can, it may require lock + * acquisition + */ + return fCurrentModel.getContentTypeIdentifier(); + } + String contentTypeId = null; IStructuredModel sModel = null; try { @@ -269,36 +279,30 @@ } public void setDocument(IDocument newDocument) { - // unhook old lifecycle listener - if(fCurrentDoc != null) { - IStructuredModel oldModel = null; - try { - oldModel = getStructuredModelForRead(fCurrentDoc); - if(oldModel != null) { - oldModel.removeModelLifecycleListener(fLifeCycleListener); - } - } finally { - if(oldModel != null) { - oldModel.releaseFromRead(); - } - } + /* + * unhook old lifecycle listener; it is important not to re-get the + * model at this point as we may be shutting down + */ + if (fCurrentModel != null) { + fCurrentModel.removeModelLifecycleListener(fLifeCycleListener); + fCurrentModel = null; } - - //set the new document + + // set the new document super.setDocument(newDocument); fCurrentDoc = newDocument; - + // add new lifecycle listener - if (newDocument != null) { - IStructuredModel newModel = null; + if (fCurrentDoc != null) { try { - newModel = getStructuredModelForRead(newDocument); - if(newModel != null) { - newModel.addModelLifecycleListener(fLifeCycleListener); + fCurrentModel = getStructuredModelForRead(fCurrentDoc); + if (fCurrentModel != null) { + fCurrentModel.addModelLifecycleListener(fLifeCycleListener); } - } finally { - if(newModel != null) { - newModel.releaseFromRead(); + } + finally { + if (fCurrentModel != null) { + fCurrentModel.releaseFromRead(); } } }