### Eclipse Workspace Patch 1.0 #P org.eclipse.wst.sse.ui 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 20 Nov 2009 20:25:08 -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,6 +30,7 @@ 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.wst.sse.ui.internal.ExtendedConfigurationBuilder; import org.eclipse.wst.sse.ui.internal.IReleasable; @@ -45,7 +50,6 @@ * 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$ /** @@ -60,6 +64,8 @@ */ private ValidatorStrategy fValidatorStrategy; + private ISourceReconcilingListener[] fReconcileListeners = new ISourceReconcilingListener[0]; + private IReconcilingStrategy fSemanticHighlightingStrategy; /** @@ -74,13 +80,24 @@ * false otherwise */ private boolean fValidationEnabled; - + + 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 +117,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 +307,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); @@ -332,7 +364,7 @@ */ public void install(ITextViewer textViewer) { super.install(textViewer); - + //determine if validation is enabled this.fValidationEnabled = SSEUIPlugin.getInstance().getPreferenceStore().getBoolean( CommonEditorPreferenceNames.EVALUATE_TEMPORARY_PROBLEMS); @@ -357,6 +389,8 @@ fSpellcheckStrategy.setDocument(null); fSpellcheckStrategy = null; } + + fReconcileListeners = new ISourceReconcilingListener[0]; } super.uninstall(); } 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 20 Nov 2009 20:25:08 -0000 @@ -41,6 +41,8 @@ import org.eclipse.jface.text.reconciler.IReconciler; import org.eclipse.jface.text.reconciler.IReconcilerExtension; import org.eclipse.jface.text.reconciler.IReconcilingStrategy; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.PlatformUI; import org.eclipse.wst.sse.ui.internal.Logger; import org.eclipse.wst.sse.ui.internal.SSEUIMessages; @@ -213,6 +215,27 @@ } } + private class PartListener implements IPartListener { + + public void partActivated(IWorkbenchPart part) { + if (part.getAdapter(ITextViewer.class) == fViewer) + forceReconciling(); + } + + public void partBroughtToTop(IWorkbenchPart part) { + } + + public void partClosed(IWorkbenchPart part) { + } + + public void partDeactivated(IWorkbenchPart part) { + } + + public void partOpened(IWorkbenchPart part) { + } + + } + /** debug flag */ protected static final boolean DEBUG; private static final long UPDATE_DELAY = 500; @@ -263,10 +286,13 @@ * true if entire document needs to be reprocessed after rewrite session */ boolean fReprocessAfterRewrite = false; + /** Part listener for focus of the text viewer */ + private IPartListener fPartListener; /** 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(); /** @@ -568,6 +594,8 @@ fViewer = textViewer; fTextInputListener = new TextInputListener(); textViewer.addTextInputListener(fTextInputListener); + fPartListener = new PartListener(); + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getPartService().addPartListener(fPartListener); setInstalled(true); } } @@ -636,6 +664,11 @@ if (!PlatformUI.isWorkbenchRunning()) return status; + if (!fHasReconciled) { + initialReconcile(); + fHasReconciled = true; + } + Thread.currentThread().setPriority(Thread.MIN_PRIORITY); boolean processed = false; try { @@ -708,6 +741,12 @@ } /** + * This method is called before the initial reconciling of the document. + */ + protected void initialReconcile() { + } + + /** * Sets the document partitioning for this reconciler. * * @param partitioning @@ -717,6 +756,13 @@ fPartitioning = partitioning; } + protected void forceReconciling() { + if (!fHasReconciled) + return; + + setEntireDocumentDirty(getDocument()); + } + /** * Basically means process the entire document. * @@ -781,6 +827,7 @@ if (isInstalled()) { // removes widget listener getTextViewer().removeTextInputListener(fTextInputListener); + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getPartService().removePartListener(fPartListener); setInstalled(false); cancel(); fIsCanceled = true; 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 20 Nov 2009 20:25:08 -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(); @@ -1828,6 +1833,9 @@ result = input.getAdapter(required); } } + else if (ITextViewer.class.equals(required)) { + return getSourceViewer(); + } else { if (result == null && internalModel != null) { result = internalModel.getAdapter(required); @@ -2633,18 +2641,49 @@ * 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])); //$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) * 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); +}