### Eclipse Workspace Patch 1.0
#P org.eclipse.ui.workbench
Index: Eclipse UI/org/eclipse/ui/LegacyHandlerSubmissionExpression.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/LegacyHandlerSubmissionExpression.java,v
retrieving revision 1.9
diff -u -r1.9 LegacyHandlerSubmissionExpression.java
--- Eclipse UI/org/eclipse/ui/LegacyHandlerSubmissionExpression.java 21 Apr 2006 20:43:38 -0000 1.9
+++ Eclipse UI/org/eclipse/ui/LegacyHandlerSubmissionExpression.java 5 May 2006 03:29:25 -0000
@@ -52,7 +52,7 @@
* true
. If this value is null
, then any
* site may be active.
*/
- private final IWorkbenchPartSite activeSite;
+ public final IWorkbenchPartSite activeSite;
/**
* Constructs a new instance of
Index: Eclipse UI/org/eclipse/ui/internal/handlers/HandlerAuthority.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/handlers/HandlerAuthority.java,v
retrieving revision 1.24
diff -u -r1.24 HandlerAuthority.java
--- Eclipse UI/org/eclipse/ui/internal/handlers/HandlerAuthority.java 11 Apr 2006 13:53:54 -0000 1.24
+++ Eclipse UI/org/eclipse/ui/internal/handlers/HandlerAuthority.java 5 May 2006 03:29:26 -0000
@@ -11,7 +11,10 @@
package org.eclipse.ui.internal.handlers;
+import java.io.PrintWriter;
+import java.io.StringWriter;
import java.util.Collection;
+import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -22,8 +25,14 @@
import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.util.Tracing;
import org.eclipse.core.expressions.Expression;
+import org.eclipse.core.expressions.IEvaluationContext;
import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.ISources;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.LegacyHandlerSubmissionExpression;
+import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.handlers.IHandlerActivation;
import org.eclipse.ui.internal.misc.Policy;
@@ -65,31 +74,31 @@
* This causes the unresolvable handler conflicts to be printed to the
* console.
*/
- private static final boolean DEBUG = Policy.DEBUG_HANDLERS;
+ public static final boolean DEBUG = Policy.DEBUG_HANDLERS;
/**
* Whether the performance information should be printed about the
* performance of the handler authority.
*/
- private static final boolean DEBUG_PERFORMANCE = Policy.DEBUG_HANDLERS_PERFORMANCE;
+ public static final boolean DEBUG_PERFORMANCE = Policy.DEBUG_HANDLERS_PERFORMANCE;
/**
* Whether the workbench command support should kick into verbose debugging
* mode. This causes the resolvable handler conflicts to be printed to the
* console.
*/
- private static final boolean DEBUG_VERBOSE = Policy.DEBUG_HANDLERS
+ public static final boolean DEBUG_VERBOSE = Policy.DEBUG_HANDLERS
&& Policy.DEBUG_HANDLERS_VERBOSE;
/**
* The command identifier to which the verbose output should be restricted.
*/
- private static final String DEBUG_VERBOSE_COMMAND_ID = Policy.DEBUG_HANDLERS_VERBOSE_COMMAND_ID;
+ public static final String DEBUG_VERBOSE_COMMAND_ID = Policy.DEBUG_HANDLERS_VERBOSE_COMMAND_ID;
/**
* The component name to print when displaying tracing information.
*/
- private static final String TRACING_COMPONENT = "HANDLERS"; //$NON-NLS-1$
+ public static final String TRACING_COMPONENT = "HANDLERS"; //$NON-NLS-1$
/**
* A bucket sort of the handler activations based on source priority of its
@@ -117,6 +126,14 @@
*/
private final Map handlerActivationsByCommandId = new HashMap();
+ private IHandlerActivation tracingNullHandlerActivation;
+
+ private Exception tracingNullStack;
+
+ private Date sourceChangedStamp;
+
+ private Date resolveConflictsStamp;
+
/**
* Constructs a new instance of HandlerAuthority
.
*
@@ -149,6 +166,9 @@
final SortedSet handlerActivations = (SortedSet) value;
if (!handlerActivations.contains(activation)) {
handlerActivations.add(activation);
+ tracingNullHandlerActivation = activation;
+ tracingNullStack = new Exception();
+ tracingNullStack.fillInStackTrace();
updateCommand(commandId, resolveConflicts(commandId,
handlerActivations));
}
@@ -160,11 +180,17 @@
handlerActivations.add(activation);
handlerActivationsByCommandId
.put(commandId, handlerActivations);
+ tracingNullHandlerActivation = activation;
+ tracingNullStack = new Exception();
+ tracingNullStack.fillInStackTrace();
updateCommand(commandId, resolveConflicts(commandId,
handlerActivations));
}
} else {
handlerActivationsByCommandId.put(commandId, activation);
+ tracingNullHandlerActivation = activation;
+ tracingNullStack = new Exception();
+ tracingNullStack.fillInStackTrace();
updateCommand(commandId, (evaluate(activation) ? activation : null));
}
@@ -172,6 +198,13 @@
final int sourcePriority = activation.getSourcePriority();
for (int i = 1; i <= 32; i++) {
if ((sourcePriority & (1 << i)) != 0) {
+ if ((DEBUG_VERBOSE)
+ && ((DEBUG_VERBOSE_COMMAND_ID == null) || (DEBUG_VERBOSE_COMMAND_ID
+ .equals(commandId)))) {
+ Tracing.printTrace(TRACING_COMPONENT, "act-handler " + DEBUG_VERBOSE_COMMAND_ID //$NON-NLS-1$
+ + " priority-bit: " + i //$NON-NLS-1$
+ + " handler: " + activation); //$NON-NLS-1$
+ }
Map activationsByExpression = activationsByExpressionBySourcePriority[i];
if (activationsByExpression == null) {
activationsByExpression = new HashMap(
@@ -208,6 +241,9 @@
handlerActivations.remove(activation);
if (handlerActivations.isEmpty()) {
handlerActivationsByCommandId.remove(commandId);
+ tracingNullHandlerActivation = activation;
+ tracingNullStack = new Exception();
+ tracingNullStack.fillInStackTrace();
updateCommand(commandId, null);
} else if (handlerActivations.size() == 1) {
@@ -215,12 +251,19 @@
.iterator().next();
handlerActivationsByCommandId.put(commandId,
remainingActivation);
+ tracingNullHandlerActivation = remainingActivation;
+ tracingNullStack = new Exception();
+ tracingNullStack.fillInStackTrace();
+
updateCommand(
commandId,
(evaluate(remainingActivation) ? remainingActivation
: null));
} else {
+ tracingNullHandlerActivation = activation;
+ tracingNullStack = new Exception();
+ tracingNullStack.fillInStackTrace();
updateCommand(commandId, resolveConflicts(commandId,
handlerActivations));
}
@@ -228,6 +271,9 @@
} else if (value instanceof IHandlerActivation) {
if (value == activation) {
handlerActivationsByCommandId.remove(commandId);
+ tracingNullHandlerActivation = activation;
+ tracingNullStack = new Exception();
+ tracingNullStack.fillInStackTrace();
updateCommand(commandId, null);
}
}
@@ -286,9 +332,16 @@
final SortedSet activations) {
// If we don't have any, then there is no match.
if (activations.isEmpty()) {
+ if ((DEBUG_VERBOSE)
+ && ((DEBUG_VERBOSE_COMMAND_ID == null) || (DEBUG_VERBOSE_COMMAND_ID
+ .equals(commandId)))) {
+ Tracing.printTrace(TRACING_COMPONENT, " rc-empty"); //$NON-NLS-1$
+ }
return null;
}
+ resolveConflictsStamp = new Date();
+
// Cycle over the activations, remembered the current best.
final Iterator activationItr = activations.iterator();
IHandlerActivation bestActivation = null;
@@ -296,6 +349,12 @@
while (activationItr.hasNext()) {
final IHandlerActivation currentActivation = (IHandlerActivation) activationItr
.next();
+ if ((DEBUG_VERBOSE)
+ && ((DEBUG_VERBOSE_COMMAND_ID == null) || (DEBUG_VERBOSE_COMMAND_ID
+ .equals(commandId)))) {
+ Tracing.printTrace(TRACING_COMPONENT, " rc-con : " + currentActivation); //$NON-NLS-1$
+ }
+
if (!evaluate(currentActivation)) {
continue; // only consider potentially active handlers
}
@@ -304,7 +363,7 @@
if ((DEBUG_VERBOSE)
&& ((DEBUG_VERBOSE_COMMAND_ID == null) || (DEBUG_VERBOSE_COMMAND_ID
.equals(commandId)))) {
- Tracing.printTrace(TRACING_COMPONENT, " resolveConflicts: eval: " + currentActivation); //$NON-NLS-1$
+ Tracing.printTrace(TRACING_COMPONENT, " rc-eval: " + currentActivation); //$NON-NLS-1$
}
if (bestActivation == null) {
bestActivation = currentActivation;
@@ -346,6 +405,57 @@
}
}
+ if ((DEBUG_VERBOSE)
+ && ((DEBUG_VERBOSE_COMMAND_ID == null) || (DEBUG_VERBOSE_COMMAND_ID
+ .equals(commandId)))) {
+ if (conflict || bestActivation == null) {
+
+ IWorkbenchWindow wwin = PlatformUI.getWorkbench()
+ .getActiveWorkbenchWindow();
+ if (wwin == null) {
+ Tracing.printTrace(TRACING_COMPONENT, " wwin is null"); //$NON-NLS-1$
+ return null;
+ }
+ IWorkbenchPage ap = wwin.getActivePage();
+ if (ap == null) {
+ Tracing.printTrace(TRACING_COMPONENT, " ap is null"); //$NON-NLS-1$
+ return null;
+ }
+ IEditorPart ae = ap.getActiveEditor();
+ if (ae == null) {
+ Tracing.printTrace(TRACING_COMPONENT, " ae is null"); //$NON-NLS-1$
+ } else {
+ boolean foundOne = false;
+ for (Iterator it = activations.iterator(); it.hasNext();) {
+ IHandlerActivation activation = (IHandlerActivation) it
+ .next();
+ Expression ex = activation.getExpression();
+ if (ex == null) {
+ Tracing.printTrace(TRACING_COMPONENT,
+ " ex is null : " + activation); //$NON-NLS-1$
+ } else {
+ if (!(ex instanceof LegacyHandlerSubmissionExpression)) {
+ Tracing
+ .printTrace(
+ TRACING_COMPONENT,
+ " ex is not instanceof LegacyHandlerSubmissionExpression: " + activation); //$NON-NLS-1$
+ } else {
+ LegacyHandlerSubmissionExpression lhex = (LegacyHandlerSubmissionExpression) ex;
+
+ if (lhex.activeSite == ae.getSite()) {
+ printTracing(wwin, ae, activation);
+ foundOne = true;
+ }
+ }
+ }
+ }
+ if (!foundOne) {
+ Tracing.printTrace(TRACING_COMPONENT,
+ " Did not find matching handler activation"); //$NON-NLS-1$
+ }
+ }
+ }
+ }
// Return the current best.
if (conflict) {
return null;
@@ -354,6 +464,50 @@
}
/**
+ * @param wwin
+ * @param ae
+ * @param activation
+ */
+ private void printTracing(IWorkbenchWindow wwin, IEditorPart ae,
+ IHandlerActivation activation) {
+
+ Tracing.printTrace(TRACING_COMPONENT,
+ " found matching handler activation: " + activation); //$NON-NLS-1$
+ ((HandlerActivation) activation).traceStamps();
+ long sc = (sourceChangedStamp==null?0L:sourceChangedStamp.getTime());
+ long rc = (resolveConflictsStamp==null?0L:resolveConflictsStamp.getTime());
+
+ Tracing
+ .printTrace(
+ TRACING_COMPONENT,
+ "\tsourceChanged: " + sc //$NON-NLS-1$
+ + " resolveConflicts: " + rc); //$NON-NLS-1$
+ Tracing
+ .printTrace(
+ TRACING_COMPONENT,
+ " matching handler activation evaluates to: " + evaluate(activation)); //$NON-NLS-1$
+
+
+ IEvaluationContext currentContext = getCurrentState();
+ Object cShell = currentContext.getVariable(ISources.ACTIVE_SHELL_NAME);
+ Object cSite = currentContext.getVariable(ISources.ACTIVE_SITE_NAME);
+ Tracing.printTrace(TRACING_COMPONENT, " current context shell: " //$NON-NLS-1$
+ + cShell + "\n\tshell-match: " //$NON-NLS-1$
+ + (cShell == wwin.getShell()));
+ Tracing.printTrace(TRACING_COMPONENT, " current context site: " //$NON-NLS-1$
+ + cSite + "\n\tsite-match: " //$NON-NLS-1$
+ + (cSite == ae.getSite()));
+
+ activation.clearResult();
+ boolean forcedEval = evaluate(activation);
+ if (forcedEval) {
+ System.out.println();
+ }
+ Tracing.printTrace(TRACING_COMPONENT, " forced evaluation: " //$NON-NLS-1$
+ + forcedEval);
+ }
+
+ /**
* Carries out the actual source change notification. It assumed that by the
* time this method is called, context
is up-to-date with the
* current state of the application.
@@ -367,6 +521,8 @@
if (DEBUG_PERFORMANCE) {
startTime = System.currentTimeMillis();
}
+
+ sourceChangedStamp = new Date();
/*
* In this first phase, we cycle through all of the activations that
@@ -391,6 +547,13 @@
if (activationItr.hasNext()) {
IHandlerActivation activation = (IHandlerActivation) activationItr
.next();
+ if ((DEBUG_VERBOSE)
+ && ((DEBUG_VERBOSE_COMMAND_ID == null) || (DEBUG_VERBOSE_COMMAND_ID
+ .equals(activation.getCommandId())))) {
+ Tracing.printTrace(TRACING_COMPONENT, "source-changed: " + DEBUG_VERBOSE_COMMAND_ID //$NON-NLS-1$
+ + " priority-bit: " + i //$NON-NLS-1$
+ + " handler: " + activation); //$NON-NLS-1$
+ }
final boolean currentActive = evaluate(activation);
activation.clearResult();
final boolean newActive = evaluate(activation);
@@ -402,6 +565,13 @@
while (activationItr.hasNext()) {
activation = (IHandlerActivation) activationItr
.next();
+ if ((DEBUG_VERBOSE)
+ && ((DEBUG_VERBOSE_COMMAND_ID == null) || (DEBUG_VERBOSE_COMMAND_ID
+ .equals(activation.getCommandId())))) {
+ Tracing.printTrace(TRACING_COMPONENT, "source-changed: " + DEBUG_VERBOSE_COMMAND_ID //$NON-NLS-1$
+ + " priority-bit: " + i //$NON-NLS-1$
+ + " handler: " + activation); //$NON-NLS-1$
+ }
// TODO After 3.2, consider making this API.
if (activation instanceof EvaluationResultCache) {
((EvaluationResultCache) activation)
@@ -412,6 +582,39 @@
changedCommandIds.add(activation
.getCommandId());
}
+ } else {
+ if(DEBUG_VERBOSE && activations.size()>1) {
+ IHandlerActivation first = (IHandlerActivation) activations.iterator().next();
+ for (Iterator it = activations.iterator(); it
+ .hasNext();) {
+ IHandlerActivation handlerActivation = (IHandlerActivation) it
+ .next();
+ if(evaluate(first)!=evaluate(handlerActivation)) {
+ ((HandlerActivation)handlerActivation).gotcha = new Exception();
+ System.out.println("GOTCHA"); //$NON-NLS-1$
+ for (Iterator it2 = activations
+ .iterator(); it2.hasNext();) {
+ HandlerActivation ha = (HandlerActivation) it2
+ .next();
+ System.out
+ .println(evaluate(ha) + " - " + ha); //$NON-NLS-1$
+ ha.eval.printStackTrace(System.out);
+ }
+ }
+// IEvaluationContext context = ((HandlerActivation) handlerActivation).context;
+// if (referenceContext != null
+// && context != null
+// && !Util.equals(referenceContext.getVariable(ISources.ACTIVE_SITE_NAME),context.getVariable(ISources.ACTIVE_SITE_NAME))) {
+// Tracing.printTrace(TRACING_COMPONENT, " MISMATCH: found context mismatch for : " + handlerActivation + " expected: " + referenceContext); //$NON-NLS-1$ //$NON-NLS-2$
+// Tracing.printTrace(TRACING_COMPONENT, " MISMATCH: non-matching context has site: " + context.getVariable(ISources.ACTIVE_SITE_NAME)); //$NON-NLS-1$
+// Tracing.printTrace(TRACING_COMPONENT, " MISMATCH: reference activation : " + referenceActivation + " expected: " + referenceContext); //$NON-NLS-1$ //$NON-NLS-2$
+// Tracing.printTrace(TRACING_COMPONENT, " MISMATCH: reference context has site: " + referenceContext.getVariable(ISources.ACTIVE_SITE_NAME)); //$NON-NLS-1$
+// } else if (referenceContext==null && context!=null) {
+// referenceContext = context;
+// referenceActivation = activation;
+// }
+ }
+ }
}
}
}
@@ -429,13 +632,22 @@
final Object value = handlerActivationsByCommandId.get(commandId);
if (value instanceof IHandlerActivation) {
final IHandlerActivation activation = (IHandlerActivation) value;
+ tracingNullHandlerActivation = activation;
+ tracingNullStack = new Exception();
+ tracingNullStack.fillInStackTrace();
updateCommand(commandId, (evaluate(activation) ? activation
: null));
} else if (value instanceof SortedSet) {
final IHandlerActivation activation = resolveConflicts(
commandId, (SortedSet) value);
+ tracingNullHandlerActivation = activation;
+ tracingNullStack = new Exception();
+ tracingNullStack.fillInStackTrace();
updateCommand(commandId, activation);
} else {
+ tracingNullHandlerActivation = null;
+ tracingNullStack = new Exception();
+ tracingNullStack.fillInStackTrace();
updateCommand(commandId, null);
}
}
@@ -465,8 +677,24 @@
final IHandlerActivation activation) {
final Command command = commandService.getCommand(commandId);
if (activation == null) {
+ if ((DEBUG_VERBOSE)
+ && ((DEBUG_VERBOSE_COMMAND_ID == null) || (DEBUG_VERBOSE_COMMAND_ID
+ .equals(commandId)))) {
+ Tracing.printTrace(TRACING_COMPONENT, "updateCommand: - " + tracingNullHandlerActivation); //$NON-NLS-1$
+ StringWriter wout = new StringWriter();
+ tracingNullStack.printStackTrace(new PrintWriter(wout));
+ Tracing.printTrace(TRACING_COMPONENT, "updateCommand: n " + wout.toString()); //$NON-NLS-1$
+ }
command.setHandler(null);
} else {
+ if ((DEBUG_VERBOSE)
+ && ((DEBUG_VERBOSE_COMMAND_ID == null) || (DEBUG_VERBOSE_COMMAND_ID
+ .equals(commandId)))) {
+ Tracing.printTrace(TRACING_COMPONENT, "updateCommand: + " + tracingNullHandlerActivation); //$NON-NLS-1$
+ StringWriter wout = new StringWriter();
+ tracingNullStack.printStackTrace(new PrintWriter(wout));
+ Tracing.printTrace(TRACING_COMPONENT, "updateCommand: s " + wout.toString()); //$NON-NLS-1$
+ }
command.setHandler(activation.getHandler());
}
}
Index: Eclipse UI/org/eclipse/ui/internal/handlers/HandlerActivation.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/handlers/HandlerActivation.java,v
retrieving revision 1.8
diff -u -r1.8 HandlerActivation.java
--- Eclipse UI/org/eclipse/ui/internal/handlers/HandlerActivation.java 18 Jan 2006 19:37:29 -0000 1.8
+++ Eclipse UI/org/eclipse/ui/internal/handlers/HandlerActivation.java 5 May 2006 03:29:26 -0000
@@ -11,7 +11,12 @@
package org.eclipse.ui.internal.handlers;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Date;
+
import org.eclipse.core.commands.IHandler;
+import org.eclipse.core.commands.util.Tracing;
import org.eclipse.core.expressions.Expression;
import org.eclipse.core.expressions.IEvaluationContext;
import org.eclipse.ui.ISources;
@@ -59,6 +64,16 @@
*/
private final IHandlerService handlerService;
+ private Date clearStamp;
+
+ private Date evaluateStamp;
+
+ private Date setStamp;
+
+ private Object cShell;
+
+ private Object cSite;
+
/**
* Constructs a new instance of HandlerActivation
.
*
@@ -123,6 +138,18 @@
final int thisDepth = this.getDepth();
final int thatDepth = activation.getDepth();
difference = thatDepth - thisDepth;
+ if (difference==0 && this!=activation) {
+ if ((HandlerAuthority.DEBUG_VERBOSE)
+ && ((HandlerAuthority.DEBUG_VERBOSE_COMMAND_ID == null) || (HandlerAuthority.DEBUG_VERBOSE_COMMAND_ID
+ .equals(commandId)))) {
+ StringWriter wout = new StringWriter();
+ Exception e = new Exception();
+ e.fillInStackTrace();
+ e.printStackTrace(new PrintWriter(wout));
+ Tracing.printTrace(HandlerAuthority.TRACING_COMPONENT, "compareTo returns 0 at " //$NON-NLS-1$
+ + wout.toString());
+ }
+ }
return difference;
}
@@ -161,4 +188,52 @@
return buffer.toString();
}
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.internal.services.EvaluationResultCache#clearResult()
+ */
+ public void clearResult() {
+ clearStamp = new Date();
+ super.clearResult();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.internal.services.EvaluationResultCache#evaluate(org.eclipse.core.expressions.IEvaluationContext)
+ */
+ public boolean evaluate(IEvaluationContext context) {
+ if (getExpression() != null && evaluationResult == null) {
+ cShell = context.getVariable(ISources.ACTIVE_SHELL_NAME);
+ cSite = context.getVariable(ISources.ACTIVE_SITE_NAME);
+ evaluateStamp = new Date();
+ }
+ return super.evaluate(context);
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.ui.internal.services.EvaluationResultCache#setResult(boolean)
+ */
+ public void setResult(boolean result) {
+ setStamp = new Date();
+ super.setResult(result);
+ }
+
+ /**
+ *
+ */
+ public void traceStamps() {
+ if ((HandlerAuthority.DEBUG_VERBOSE)
+ && ((HandlerAuthority.DEBUG_VERBOSE_COMMAND_ID == null) || (HandlerAuthority.DEBUG_VERBOSE_COMMAND_ID
+ .equals(commandId)))) {
+ long eval = (evaluateStamp==null?0L:evaluateStamp.getTime());
+ long set = (setStamp==null?0L:setStamp.getTime());
+ long clear = (clearStamp==null?0L:clearStamp.getTime());
+ Tracing.printTrace(HandlerAuthority.TRACING_COMPONENT,
+ " activation-eval: " + eval //$NON-NLS-1$
+ + " activation-set: " + set //$NON-NLS-1$
+ + " activation-clean: " + clear); //$NON-NLS-1$
+ Tracing.printTrace(HandlerAuthority.TRACING_COMPONENT,
+ " last evaluate used shell: " + cShell //$NON-NLS-1$
+ + " site: " + cSite); //$NON-NLS-1$
+ }
+ }
}
Index: Eclipse UI/org/eclipse/ui/internal/SaveablesList.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/SaveablesList.java,v
retrieving revision 1.6
diff -u -r1.6 SaveablesList.java
--- Eclipse UI/org/eclipse/ui/internal/SaveablesList.java 27 Apr 2006 17:50:01 -0000 1.6
+++ Eclipse UI/org/eclipse/ui/internal/SaveablesList.java 5 May 2006 03:29:26 -0000
@@ -49,6 +49,7 @@
import org.eclipse.ui.ISaveablePart2;
import org.eclipse.ui.ISaveablesLifecycleListener;
import org.eclipse.ui.ISaveablesSource;
+import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPreferenceConstants;
import org.eclipse.ui.IWorkbenchWindow;
@@ -58,6 +59,7 @@
import org.eclipse.ui.dialogs.ListSelectionDialog;
import org.eclipse.ui.internal.dialogs.EventLoopProgressMonitor;
import org.eclipse.ui.internal.util.PrefUtil;
+import org.eclipse.ui.internal.util.Util;
import org.eclipse.ui.model.WorkbenchPartLabelProvider;
/**
@@ -184,15 +186,14 @@
break;
case SaveablesLifecycleEvent.PRE_CLOSE:
Saveable[] models = event.getSaveables();
- Map modelsDecrementing = new HashMap();
- Set modelsClosing = new HashSet();
+ CloseInfo closeInfo = new CloseInfo();
for (int i = 0; i < models.length; i++) {
- incrementRefCount(modelsDecrementing, models[i]);
+ incrementRefCount(closeInfo.modelsDecrementing, models[i]);
}
- fillModelsClosing(modelsClosing, modelsDecrementing);
+ fillModelsToSave(closeInfo);
boolean canceled = promptForSavingIfNecessary(PlatformUI
- .getWorkbench().getActiveWorkbenchWindow(), modelsClosing, modelsDecrementing,
+ .getWorkbench().getActiveWorkbenchWindow(), closeInfo,
!event.isForce());
if (canceled) {
event.setVeto(true);
@@ -289,50 +290,111 @@
* @param editorsToClose
* @param save
* @param window
- * @return the post close info to be passed to postClose
+ * @return the close info to be passed to postClose, or null if the user canceled
*/
public Object preCloseParts(List editorsToClose, boolean save,
final IWorkbenchWindow window) {
// reference count (how many occurrences of a model will go away?)
- PostCloseInfo postCloseInfo = new PostCloseInfo();
+ CloseInfo closeInfo = new CloseInfo();
+
+ // Process all parts that implement ISaveablePart or ISaveablePart2.
+ // Some of these will not want a prompt, or want to prompt on their
+ // own. We then need to restore the workbench to its previous state,
+ // for now this is just last active perspective.
+ // Note that the given parts may come from multiple
+ // windows, pages and perspectives.
+ WorkbenchPage currentPage = null;
+ Perspective currentPageOriginalPerspective = null;
for (Iterator it = editorsToClose.iterator(); it.hasNext();) {
IWorkbenchPart part = (IWorkbenchPart) it.next();
- postCloseInfo.partsClosing.add(part);
- if (part instanceof ISaveablePart) {
- ISaveablePart saveablePart = (ISaveablePart) part;
- if (save && !saveablePart.isSaveOnCloseNeeded()) {
- // pretend for now that this part is not closing
- continue;
- }
- }
- if (save && part instanceof ISaveablePart2) {
- ISaveablePart2 saveablePart2 = (ISaveablePart2) part;
- // TODO show saveablePart2 before prompting, see
- // EditorManager.saveAll
- int response = SaveableHelper.savePart(saveablePart2, window,
- true);
- // only include this part in the following logic if it returned
- // DEFAULT
- if (response != ISaveablePart2.DEFAULT) {
- continue;
+ closeInfo.partsClosing.add(part);
+ boolean promptForPart = true;
+ if (save) {
+ if (part instanceof ISaveablePart) {
+ ISaveablePart saveablePart = (ISaveablePart) part;
+ if (!saveablePart.isSaveOnCloseNeeded()) {
+ promptForPart = false;
+ }
+ }
+ if (promptForPart && part instanceof ISaveablePart2) {
+ WorkbenchPage page = (WorkbenchPage) part.getSite()
+ .getPage();
+ if (!Util.equals(currentPage, page)) {
+ if (currentPage != null
+ && currentPageOriginalPerspective != null) {
+ if (!currentPageOriginalPerspective
+ .equals(currentPage.getActivePerspective())) {
+ currentPage
+ .setPerspective(currentPageOriginalPerspective
+ .getDesc());
+ }
+ }
+ currentPage = page;
+ currentPageOriginalPerspective = page
+ .getActivePerspective();
+ }
+ if (part instanceof IViewPart) {
+ Perspective perspective = page
+ .getFirstPerspectiveWithView((IViewPart) part);
+ if (perspective != null) {
+ page.setPerspective(perspective.getDesc());
+ }
+ }
+ // show the window containing the page?
+ IWorkbenchWindow partsWindow = page
+ .getWorkbenchWindow();
+ if (partsWindow != partsWindow.getWorkbench()
+ .getActiveWorkbenchWindow()) {
+ Shell shell = partsWindow.getShell();
+ if (shell.getMinimized()) {
+ shell.setMinimized(false);
+ }
+ shell.setActive();
+ }
+ page.bringToTop(part);
+ // try to save the part
+ int choice = SaveableHelper.savePart((ISaveablePart2) part,
+ page.getWorkbenchWindow(), true);
+ if (choice == ISaveablePart2.CANCEL) {
+ // If the user cancels, don't restore the previous
+ // workbench state, as that will
+ // be an unexpected switch from the current state.
+ return null;
+ } else if (choice != ISaveablePart2.DEFAULT) {
+ promptForPart = false;
+ }
}
}
Saveable[] modelsFromSource = getSaveables(part);
for (int i = 0; i < modelsFromSource.length; i++) {
- incrementRefCount(postCloseInfo.modelsDecrementing,
- modelsFromSource[i]);
+ incrementRefCount(closeInfo.modelsDecrementing, modelsFromSource[i]);
+ if(!promptForPart) {
+ incrementRefCount(closeInfo.modelsDecrementingWithoutPrompt, modelsFromSource[i]);
+ }
+ }
+ if (!promptForPart) {
+ closeInfo.modelsNotToSave.addAll(Arrays.asList(modelsFromSource));
}
}
- fillModelsClosing(postCloseInfo.modelsClosing,
- postCloseInfo.modelsDecrementing);
+
+ // try to restore the workbench to its previous state
+ if (currentPage != null && currentPageOriginalPerspective != null) {
+ if (!currentPageOriginalPerspective.equals(currentPage
+ .getActivePerspective())) {
+ currentPage.setPerspective(currentPageOriginalPerspective
+ .getDesc());
+ }
+ }
+
+ fillModelsToSave(closeInfo);
+
if (save) {
- boolean canceled = promptForSavingIfNecessary(window,
- postCloseInfo.modelsClosing, postCloseInfo.modelsDecrementing, true);
+ boolean canceled = promptForSavingIfNecessary(window, closeInfo, true);
if (canceled) {
return null;
}
}
- return postCloseInfo;
+ return closeInfo;
}
/**
@@ -342,11 +404,13 @@
* @return true if the user canceled
*/
private boolean promptForSavingIfNecessary(final IWorkbenchWindow window,
- Set modelsClosing, Map modelsDecrementing, boolean canCancel) {
+ CloseInfo closeInfo, boolean canCancel) {
List modelsToOptionallySave = new ArrayList();
- for (Iterator it = modelsDecrementing.keySet().iterator(); it.hasNext();) {
+ for (Iterator it = closeInfo.modelsDecrementing.keySet().iterator(); it.hasNext();) {
Saveable modelDecrementing = (Saveable) it.next();
- if (modelDecrementing.isDirty() && !modelsClosing.contains(modelDecrementing)) {
+ if (modelDecrementing.isDirty()
+ && !closeInfo.modelsToSave.contains(modelDecrementing)
+ && !closeInfo.modelsNotToSave.contains(modelDecrementing)) {
modelsToOptionallySave.add(modelDecrementing);
}
}
@@ -359,7 +423,7 @@
}
List modelsToSave = new ArrayList();
- for (Iterator it = modelsClosing.iterator(); it.hasNext();) {
+ for (Iterator it = closeInfo.modelsToSave.iterator(); it.hasNext();) {
Saveable modelClosing = (Saveable) it.next();
if (modelClosing.isDirty()) {
modelsToSave.add(modelClosing);
@@ -372,12 +436,20 @@
/**
* @param modelsClosing
* @param modelsDecrementing
+ * @param partsWithoutPrompt
*/
- private void fillModelsClosing(Set modelsClosing, Map modelsDecrementing) {
- for (Iterator it = modelsDecrementing.keySet().iterator(); it.hasNext();) {
+ private void fillModelsToSave(CloseInfo closeInfo) {
+ for (Iterator it = closeInfo.modelsDecrementing.keySet().iterator(); it.hasNext();) {
Saveable model = (Saveable) it.next();
- if (modelsDecrementing.get(model).equals(modelRefCounts.get(model))) {
- modelsClosing.add(model);
+ Integer refCount = (Integer) closeInfo.modelsDecrementing.get(model);
+ if (refCount.equals(modelRefCounts.get(model))) {
+ // model will be closed. Figure out if we need to prompt
+ Integer refCountForNotPrompting = (Integer) closeInfo.modelsDecrementingWithoutPrompt.get(model);
+ if (refCountForNotPrompting==null || refCountForNotPrompting.intValue() < refCount.intValue()) {
+ closeInfo.modelsToSave.add(model);
+ } else {
+ // all ref counts come from parts that decided not to prompt.
+ }
}
}
}
@@ -550,21 +622,30 @@
return false;
}
- private static class PostCloseInfo {
+ private static class CloseInfo {
+ // parts that are being closed
private List partsClosing = new ArrayList();
-
+
+ // reference counts for all models that will be closed
private Map modelsDecrementing = new HashMap();
- private Set modelsClosing = new HashSet();
+ // reference counts for models that will be closed (but no prompting for save for these)
+ private Map modelsDecrementingWithoutPrompt = new HashMap();
+
+ // models that are to be saved
+ private Set modelsToSave = new HashSet();
+
+ // models that are not to be saved
+ private Set modelsNotToSave = new HashSet();
}
/**
- * @param postCloseInfoObject
+ * @param closeInfoObject
*/
- public void postClose(Object postCloseInfoObject) {
- PostCloseInfo postCloseInfo = (PostCloseInfo) postCloseInfoObject;
+ public void postClose(Object closeInfoObject) {
+ CloseInfo closeInfo = (CloseInfo) closeInfoObject;
List removed = new ArrayList();
- for (Iterator it = postCloseInfo.partsClosing.iterator(); it.hasNext();) {
+ for (Iterator it = closeInfo.partsClosing.iterator(); it.hasNext();) {
IWorkbenchPart part = (IWorkbenchPart) it.next();
Set saveables = (Set) modelMap.get(part);
if (saveables != null) {
Index: Eclipse UI/org/eclipse/ui/internal/PartSite.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/PartSite.java,v
retrieving revision 1.85
diff -u -r1.85 PartSite.java
--- Eclipse UI/org/eclipse/ui/internal/PartSite.java 24 Feb 2006 18:36:13 -0000 1.85
+++ Eclipse UI/org/eclipse/ui/internal/PartSite.java 5 May 2006 03:29:25 -0000
@@ -536,6 +536,8 @@
buffer.append(getPluginId());
buffer.append(",registeredName="); //$NON-NLS-1$
buffer.append(getRegisteredName());
+ buffer.append(",hashCode="); //$NON-NLS-1$
+ buffer.append(hashCode());
buffer.append(')');
return buffer.toString();
}
Index: Eclipse UI/org/eclipse/ui/internal/services/EvaluationResultCache.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/services/EvaluationResultCache.java,v
retrieving revision 1.7
diff -u -r1.7 EvaluationResultCache.java
--- Eclipse UI/org/eclipse/ui/internal/services/EvaluationResultCache.java 24 Feb 2006 18:36:23 -0000 1.7
+++ Eclipse UI/org/eclipse/ui/internal/services/EvaluationResultCache.java 5 May 2006 03:29:26 -0000
@@ -32,19 +32,25 @@
* The previous computed evaluation result. If no evaluation result is
* available, then this value is null
.
*/
- private EvaluationResult evaluationResult = null;
+ public EvaluationResult evaluationResult = null;
/**
* The expression to evaluate. This value may be null
, in
* which case the evaluation result is always true
.
*/
private final Expression expression;
+
+ public IEvaluationContext context;
/**
* The priority that has been given to this expression.
*/
private final int sourcePriority;
+ public Exception eval;
+
+ public Exception gotcha;
+
/**
* Constructs a new instance of EvaluationResultCache
.
*
@@ -60,17 +66,21 @@
.computeSourcePriority(expression);
}
- public final void clearResult() {
+ public void clearResult() {
evaluationResult = null;
+ context = null;
+ eval = null;
+ gotcha = null;
}
- public final boolean evaluate(final IEvaluationContext context) {
+ public boolean evaluate(final IEvaluationContext context) {
if (expression == null) {
return true;
}
if (evaluationResult == null) {
try {
+ this.eval = new Exception();
evaluationResult = expression.evaluate(context);
} catch (final CoreException e) {
/*
@@ -100,7 +110,9 @@
* @param result
* The cached result to use.
*/
- public final void setResult(final boolean result) {
+ public void setResult(final boolean result) {
+ eval = new Exception();
+ gotcha = null;
if (result) {
evaluationResult = EvaluationResult.TRUE;
} else {