### Eclipse Workspace Patch 1.0 #P org.eclipse.wst.sse.ui Index: src/org/eclipse/wst/sse/ui/StructuredTextViewerConfiguration.java =================================================================== RCS file: /cvsroot/webtools/sourceediting/plugins/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredTextViewerConfiguration.java,v retrieving revision 1.46 diff -u -r1.46 StructuredTextViewerConfiguration.java --- src/org/eclipse/wst/sse/ui/StructuredTextViewerConfiguration.java 26 Aug 2009 20:50:37 -0000 1.46 +++ src/org/eclipse/wst/sse/ui/StructuredTextViewerConfiguration.java 22 Oct 2009 22:35:18 -0000 @@ -50,6 +50,7 @@ import org.eclipse.ui.editors.text.EditorsUI; import org.eclipse.ui.editors.text.TextSourceViewerConfiguration; import org.eclipse.ui.texteditor.ChainedPreferenceStore; +import org.eclipse.ui.texteditor.ITextEditor; import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredPartitioning; import org.eclipse.wst.sse.core.internal.text.rules.StructuredTextPartitioner; import org.eclipse.wst.sse.ui.internal.ExtendedConfigurationBuilder; @@ -107,7 +108,8 @@ private final String AUTOEDITSTRATEGY = "autoeditstrategy"; private ReconcilerHighlighter fHighlighter = null; - + + private ITextEditor fEditor = null; /** * Creates a structured text viewer configuration. */ @@ -602,7 +604,7 @@ if (sourceViewer != null) { //Only create reconciler if sourceViewer is present if (fReconciler == null && sourceViewer != null) { - StructuredRegionProcessor newReconciler = new StructuredRegionProcessor(); + StructuredRegionProcessor newReconciler = new StructuredRegionProcessor(fEditor); // reconciler configurations newReconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer)); @@ -688,4 +690,8 @@ public void setHighlighter(ReconcilerHighlighter highlighter) { fHighlighter = highlighter; } + + public void setEditor(ITextEditor editor) { + fEditor = editor; + } } Index: src/org/eclipse/wst/sse/ui/StructuredTextEditor.java =================================================================== RCS file: /cvsroot/webtools/sourceediting/plugins/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/StructuredTextEditor.java,v retrieving revision 1.110 diff -u -r1.110 StructuredTextEditor.java --- src/org/eclipse/wst/sse/ui/StructuredTextEditor.java 26 Aug 2009 20:50:37 -0000 1.110 +++ src/org/eclipse/wst/sse/ui/StructuredTextEditor.java 22 Oct 2009 22:35:18 -0000 @@ -185,6 +185,7 @@ 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.reconcile.DocumentRegionProcessor; +import org.eclipse.wst.sse.ui.internal.reconcile.ISourceReconcilingListener; 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; @@ -859,7 +860,11 @@ private OutlinePageListener fOutlinePageListener = null; /** This editor's projection support */ private ProjectionSupport fProjectionSupport; + private IPropertySheetPage fPropertySheetPage; + + private ISourceReconcilingListener[] fReconcilingListeners = new ISourceReconcilingListener[0]; + private String fRememberTitle; /** The ruler context menu to be disposed. */ private Menu fRulerContextMenu; @@ -1289,7 +1294,7 @@ fInformationPresenter = new InformationPresenter(informationControlCreator); fInformationPresenter.setSizeConstraints(60, 10, true, true); fInformationPresenter.install(getSourceViewer()); - + addReconcilingListeners(getSourceViewerConfiguration(), getTextViewer()); installSemanticHighlighting(); @@ -1420,6 +1425,7 @@ String targetid = getClass().getName() + "#default"; //$NON-NLS-1$ cat = new ConfigurationAndTarget(targetid, cfg); } + cfg.setEditor(this); return cat; } @@ -2633,18 +2639,48 @@ * 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 + /* + * There should be no need to unconfigure before configure because + * configure will also unconfigure before configuring + */ + removeReconcilingListeners(oldSourceViewerConfiguration, stv); stv.unconfigure(); 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])); + } + fReconcilingListeners = (ISourceReconcilingListener[]) reconcilingListeners.toArray(new ISourceReconcilingListener[reconcilingListeners.size()]); + } + catch (ClassCastException e) { + // TODO: report bad runtime configuration + } + + IReconciler reconciler = config.getReconciler(stv); + if (reconciler instanceof DocumentRegionProcessor) { + for (int i = 0; i < fReconcilingListeners.length; i++) + ((DocumentRegionProcessor) reconciler).addReconcilingListener(fReconcilingListeners[i]); + } + } /* * (non-Javadoc) * Index: src/org/eclipse/wst/sse/ui/internal/reconcile/StructuredRegionProcessor.java =================================================================== RCS file: /cvsroot/webtools/sourceediting/plugins/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/StructuredRegionProcessor.java,v retrieving revision 1.32 diff -u -r1.32 StructuredRegionProcessor.java --- src/org/eclipse/wst/sse/ui/internal/reconcile/StructuredRegionProcessor.java 26 Aug 2009 01:39:47 -0000 1.32 +++ src/org/eclipse/wst/sse/ui/internal/reconcile/StructuredRegionProcessor.java 22 Oct 2009 22:35:18 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2001, 2007 IBM Corporation and others. + * Copyright (c) 2001, 2009 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 @@ -14,6 +14,7 @@ import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.reconciler.DirtyRegion; +import org.eclipse.ui.texteditor.ITextEditor; import org.eclipse.wst.sse.core.StructuredModelManager; import org.eclipse.wst.sse.core.internal.model.ModelLifecycleEvent; import org.eclipse.wst.sse.core.internal.provisional.IModelLifecycleListener; @@ -74,6 +75,14 @@ private IModelLifecycleListener fLifeCycleListener = new ModelLifecycleListener(); IStructuredModel fCurrentModel = null; + public StructuredRegionProcessor(ITextEditor editor) { + super(editor); + } + + public StructuredRegionProcessor() { + super(); + } + /* * (non-Javadoc) * Index: src/org/eclipse/wst/sse/ui/internal/reconcile/DocumentRegionProcessor.java =================================================================== RCS file: /cvsroot/webtools/sourceediting/plugins/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/DocumentRegionProcessor.java,v retrieving revision 1.23 diff -u -r1.23 DocumentRegionProcessor.java --- src/org/eclipse/wst/sse/ui/internal/reconcile/DocumentRegionProcessor.java 28 Sep 2009 14:54:44 -0000 1.23 +++ src/org/eclipse/wst/sse/ui/internal/reconcile/DocumentRegionProcessor.java 22 Oct 2009 22:35:18 -0000 @@ -14,8 +14,12 @@ import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.content.IContentDescription; import org.eclipse.core.runtime.content.IContentType; @@ -26,7 +30,14 @@ import org.eclipse.jface.text.Region; import org.eclipse.jface.text.reconciler.DirtyRegion; import org.eclipse.jface.text.reconciler.IReconcilingStrategy; +import org.eclipse.jface.text.source.IAnnotationModel; import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.swt.events.ShellAdapter; +import org.eclipse.swt.events.ShellEvent; +import org.eclipse.swt.widgets.Control; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.texteditor.ITextEditor; import org.eclipse.wst.sse.ui.internal.ExtendedConfigurationBuilder; import org.eclipse.wst.sse.ui.internal.IReleasable; import org.eclipse.wst.sse.ui.internal.Logger; @@ -45,9 +56,41 @@ * validator strategies - DirtyRegion processing logic. */ public class DocumentRegionProcessor extends DirtyRegionProcessor { - private static final boolean DEBUG_VALIDATORS = Boolean.TRUE.toString().equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.ui/debug/reconcilerValidators")); //$NON-NLS-1$ + private class PartListener implements IPartListener { + + public void partActivated(IWorkbenchPart part) { + if (part.getAdapter(ITextEditor.class) == fEditor) + forceReconciling(); + } + + public void partBroughtToTop(IWorkbenchPart part) { + } + + public void partClosed(IWorkbenchPart part) { + } + + public void partDeactivated(IWorkbenchPart part) { + } + + public void partOpened(IWorkbenchPart part) { + } + + } + + private class ActivationListener extends ShellAdapter { + private Control fControl; + + public ActivationListener(Control control) { + fControl = control; + } + + public void shellActivated(ShellEvent e) { + if (!fControl.isDisposed() && fControl.isVisible()) + forceReconciling(); + } + } /** * A strategy to use the defined default Spelling service. */ @@ -60,6 +103,8 @@ */ private ValidatorStrategy fValidatorStrategy; + private ISourceReconcilingListener[] fReconcileListeners = new ISourceReconcilingListener[0]; + private IReconcilingStrategy fSemanticHighlightingStrategy; /** @@ -74,13 +119,37 @@ * false otherwise */ private boolean fValidationEnabled; - + + private ITextEditor fEditor; + private IPartListener fPartListener; + private ActivationListener fShellListener; + + private boolean fHasReconciled = false; + + public DocumentRegionProcessor() { + } + + public DocumentRegionProcessor(ITextEditor editor) { + fEditor = editor; + } + + public void addReconcilingListener(ISourceReconcilingListener listener) { + Set listeners = new HashSet(Arrays.asList(fReconcileListeners)); + listeners.add(listener); + fReconcileListeners = (ISourceReconcilingListener[]) listeners.toArray(new ISourceReconcilingListener[listeners.size()]); + } + protected void beginProcessing() { super.beginProcessing(); ValidatorStrategy validatorStrategy = getValidatorStrategy(); if (validatorStrategy != null) { validatorStrategy.beginProcessing(); } + if ((getTextViewer() instanceof ISourceViewer)) { + for (int i = 0; i < fReconcileListeners.length; i++) { + fReconcileListeners[i].aboutToBeReconciled(); + } + } } protected void endProcessing() { @@ -100,6 +169,14 @@ if (semanticHighlightingStrategy != null && document != null) { semanticHighlightingStrategy.reconcile(new Region(0, document.getLength())); } + + if ((getTextViewer() instanceof ISourceViewer)) { + ISourceViewer sourceViewer = (ISourceViewer) getTextViewer(); + IAnnotationModel annotationModel = sourceViewer.getAnnotationModel(); + for (int i = 0; i < fReconcileListeners.length; i++) { + fReconcileListeners[i].reconciled(document, annotationModel, false, new NullProgressMonitor()); + } + } } protected String getContentType(IDocument doc) { @@ -282,6 +359,13 @@ getFoldingStrategy().reconcile(dirtyRegion, null); } } + + public void removeReconcilingListener(ISourceReconcilingListener listener) { + Set listeners = new HashSet(Arrays.asList(fReconcileListeners)); + listeners.remove(listener); + fReconcileListeners = (ISourceReconcilingListener[]) listeners.toArray(new ISourceReconcilingListener[listeners.size()]); + } + public void setDocument(IDocument doc) { super.setDocument(doc); @@ -298,6 +382,13 @@ fFoldingStrategy = null; } + protected void forceReconciling() { + if (!fHasReconciled) + return; + + setEntireDocumentDirty(getDocument()); + } + protected void setEntireDocumentDirty(IDocument document) { super.setEntireDocumentDirty(document); @@ -332,6 +423,14 @@ */ public void install(ITextViewer textViewer) { super.install(textViewer); + + fShellListener = new ActivationListener(textViewer.getTextWidget()); + textViewer.getTextWidget().getShell().addShellListener(fShellListener); + + if (fEditor != null) { + fPartListener = new PartListener(); + fEditor.getSite().getWorkbenchWindow().getPartService().addPartListener(fPartListener); + } //determine if validation is enabled this.fValidationEnabled = SSEUIPlugin.getInstance().getPreferenceStore().getBoolean( @@ -344,6 +443,11 @@ public void uninstall() { if (isInstalled()) { + if (fEditor != null) { + fEditor.getSite().getWorkbenchWindow().getPartService().removePartListener(fPartListener); + } + getTextViewer().getTextWidget().getShell().removeShellListener(fShellListener); + cancel(); IReconcilingStrategy validatorStrategy = getValidatorStrategy(); @@ -357,7 +461,14 @@ fSpellcheckStrategy.setDocument(null); fSpellcheckStrategy = null; } + + fReconcileListeners = new ISourceReconcilingListener[0]; } super.uninstall(); } + + protected void initialReconcile() { + super.initialReconcile(); + fHasReconciled = true; + } } Index: src/org/eclipse/wst/sse/ui/internal/reconcile/DirtyRegionProcessor.java =================================================================== RCS file: /cvsroot/webtools/sourceediting/plugins/org.eclipse.wst.sse.ui/src/org/eclipse/wst/sse/ui/internal/reconcile/DirtyRegionProcessor.java,v retrieving revision 1.35 diff -u -r1.35 DirtyRegionProcessor.java --- src/org/eclipse/wst/sse/ui/internal/reconcile/DirtyRegionProcessor.java 20 Oct 2009 14:19:40 -0000 1.35 +++ src/org/eclipse/wst/sse/ui/internal/reconcile/DirtyRegionProcessor.java 22 Oct 2009 22:35:18 -0000 @@ -267,6 +267,7 @@ /** The job should be reset because of document changes */ private boolean fReset = false; private boolean fIsCanceled = false; + private boolean fHasReconciled = false; private Object LOCK = new Object(); /** @@ -636,6 +637,11 @@ if (!PlatformUI.isWorkbenchRunning()) return status; + if (!fHasReconciled) { + initialReconcile(); + fHasReconciled = true; + } + Thread.currentThread().setPriority(Thread.MIN_PRIORITY); boolean processed = false; try { @@ -708,6 +714,12 @@ } /** + * This method is called before the initial reconciling of the document. + */ + protected void initialReconcile() { + } + + /** * Sets the document partitioning for this reconciler. * * @param partitioning Index: src/org/eclipse/wst/sse/ui/internal/reconcile/ISourceReconcilingListener.java =================================================================== RCS file: src/org/eclipse/wst/sse/ui/internal/reconcile/ISourceReconcilingListener.java diff -N src/org/eclipse/wst/sse/ui/internal/reconcile/ISourceReconcilingListener.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/wst/sse/ui/internal/reconcile/ISourceReconcilingListener.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2009 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 + *******************************************************************************/ + +package org.eclipse.wst.sse.ui.internal.reconcile; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.text.IDocument; +import org.eclipse.jface.text.source.IAnnotationModel; + +/** + * A course listener for source viewer "reconciling" of a document + * + */ +public interface ISourceReconcilingListener { + + /** + * Called before reconciling is started. + */ + void aboutToBeReconciled(); + + /** + * Called after reconciling has been finished. + * + * @param document + * the text document or null if reconciliation has + * been cancelled + * @param model + * the annotation model that was changed or null + * if reconciliation has been cancelled + * @param forced + * true iff this reconciliation was forced + * @param progressMonitor + * the progress monitor + */ + void reconciled(IDocument document, IAnnotationModel model, boolean forced, IProgressMonitor progressMonitor); +}