Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Webster2013-05-14 16:16:06 +0000
committerPaul Webster2013-05-23 16:05:50 +0000
commite41dbc7b42e73b036f7e54669e0197b3554ec0e2 (patch)
tree74308e88cd41a2f49b610135f142bf8f235943a7
parentcbcfb2fc143bf90b639cedcf8c1acaab21089cef (diff)
downloadeclipse.platform.ui-e41dbc7b42e73b036f7e54669e0197b3554ec0e2.tar.gz
eclipse.platform.ui-e41dbc7b42e73b036f7e54669e0197b3554ec0e2.tar.xz
eclipse.platform.ui-e41dbc7b42e73b036f7e54669e0197b3554ec0e2.zip
Bug 405562 - Save All saves only the selected Saveables in a
ISaveablePart A different approach, go through the ui.workbench saveable code. Change-Id: I82aa5c52c35e43a4fcf9d9f07174b495418786f8
-rw-r--r--bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/WBWRenderer.java7
-rw-r--r--bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceImpl.java33
-rw-r--r--bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceSaveHandler.java133
-rw-r--r--bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/workbench/modeling/ISaveHandler.java4
-rw-r--r--bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/SaveAction.java13
-rw-r--r--bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/SaveableHelper.java28
-rw-r--r--bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/Workbench.java2
-rw-r--r--bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java506
-rw-r--r--bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java45
-rw-r--r--bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/handlers/SaveAllHandler.java87
-rw-r--r--bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/handlers/SaveHandler.java95
-rw-r--r--tests/org.eclipse.e4.ui.tests/src/org/eclipse/e4/ui/tests/application/EPartServiceTest.java8
-rw-r--r--tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/api/APITestUtils.java6
13 files changed, 786 insertions, 181 deletions
diff --git a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/WBWRenderer.java b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/WBWRenderer.java
index 044723dd685..5f06e43a77e 100644
--- a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/WBWRenderer.java
+++ b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/WBWRenderer.java
@@ -25,6 +25,7 @@ import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.core.services.log.Logger;
import org.eclipse.e4.ui.internal.workbench.Activator;
import org.eclipse.e4.ui.internal.workbench.E4Workbench;
+import org.eclipse.e4.ui.internal.workbench.PartServiceSaveHandler;
import org.eclipse.e4.ui.internal.workbench.Policy;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.MContext;
@@ -460,7 +461,7 @@ public class WBWRenderer extends SWTPartRenderer {
return wbwShell;
}
});
- localContext.set(ISaveHandler.class, new ISaveHandler() {
+ final PartServiceSaveHandler saveHandler = new PartServiceSaveHandler() {
public Save promptToSave(MPart dirtyPart) {
Shell shell = (Shell) context
.get(IServiceConstants.ACTIVE_SHELL);
@@ -488,7 +489,9 @@ public class WBWRenderer extends SWTPartRenderer {
}
return response;
}
- });
+ };
+ saveHandler.logger = logger;
+ localContext.set(ISaveHandler.class, saveHandler);
if (wbwModel.getLabel() != null)
wbwShell.setText(wbwModel.getLocalizedLabel());
diff --git a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceImpl.java b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceImpl.java
index ea87aee6706..a5c3383eb1f 100644
--- a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceImpl.java
+++ b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceImpl.java
@@ -54,7 +54,6 @@ import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import org.eclipse.e4.ui.workbench.modeling.IPartListener;
import org.eclipse.e4.ui.workbench.modeling.ISaveHandler;
-import org.eclipse.e4.ui.workbench.modeling.ISaveHandler.Save;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.osgi.util.NLS;
@@ -1207,15 +1206,8 @@ public class PartServiceImpl implements EPartService {
return true;
}
- if (confirm && saveHandler != null) {
- switch (saveHandler.promptToSave(part)) {
- case NO:
- return true;
- case CANCEL:
- return false;
- case YES:
- break;
- }
+ if (saveHandler != null) {
+ return saveHandler.save(part, confirm);
}
Object client = part.getObject();
@@ -1238,25 +1230,8 @@ public class PartServiceImpl implements EPartService {
if (dirtyParts.isEmpty()) {
return true;
}
-
- if (confirm && saveHandler != null) {
- List<MPart> dirtyPartsList = Collections.unmodifiableList(new ArrayList<MPart>(
- dirtyParts));
- Save[] decisions = saveHandler.promptToSave(dirtyPartsList);
- for (Save decision : decisions) {
- if (decision == Save.CANCEL) {
- return false;
- }
- }
-
- for (int i = 0; i < decisions.length; i++) {
- if (decisions[i] == Save.YES) {
- if (!savePart(dirtyPartsList.get(i), false)) {
- return false;
- }
- }
- }
- return true;
+ if (saveHandler != null) {
+ return saveHandler.saveParts(dirtyParts, confirm);
}
for (MPart dirtyPart : dirtyParts) {
diff --git a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceSaveHandler.java b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceSaveHandler.java
new file mode 100644
index 00000000000..9d68c8fe93a
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/internal/workbench/PartServiceSaveHandler.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2013 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.e4.ui.internal.workbench;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import org.eclipse.e4.core.contexts.ContextInjectionFactory;
+import org.eclipse.e4.core.di.InjectionException;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.ui.di.Persist;
+import org.eclipse.e4.ui.model.application.ui.basic.MPart;
+import org.eclipse.e4.ui.workbench.modeling.ISaveHandler;
+import org.eclipse.osgi.util.NLS;
+
+public class PartServiceSaveHandler implements ISaveHandler {
+
+ public Logger logger;
+
+ private void log(String unidentifiedMessage, String identifiedMessage, String id, Exception e) {
+ if (logger == null) {
+ return;
+ }
+ if (id == null || id.length() == 0) {
+ logger.error(e, unidentifiedMessage);
+ } else {
+ logger.error(e, NLS.bind(identifiedMessage, id));
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see
+ * org.eclipse.e4.ui.workbench.modeling.ISaveHandler#save(org.eclipse.e4.ui.model.application
+ * .ui.basic.MPart, boolean)
+ */
+ public boolean save(MPart dirtyPart, boolean confirm) {
+ if (confirm) {
+ switch (promptToSave(dirtyPart)) {
+ case NO:
+ return true;
+ case CANCEL:
+ return false;
+ case YES:
+ break;
+ }
+ }
+
+ Object client = dirtyPart.getObject();
+ try {
+ ContextInjectionFactory.invoke(client, Persist.class, dirtyPart.getContext());
+ } catch (InjectionException e) {
+ log("Failed to persist contents of part", "Failed to persist contents of part ({0})", //$NON-NLS-1$ //$NON-NLS-2$
+ dirtyPart.getElementId(), e);
+ return false;
+ } catch (RuntimeException e) {
+ log("Failed to persist contents of part via DI", //$NON-NLS-1$
+ "Failed to persist contents of part ({0}) via DI", dirtyPart.getElementId(), e); //$NON-NLS-1$
+ return false;
+ }
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.e4.ui.workbench.modeling.ISaveHandler#saveParts(java.util.Collection,
+ * boolean)
+ */
+ public boolean saveParts(Collection<MPart> dirtyParts, boolean confirm) {
+ if (confirm) {
+ List<MPart> dirtyPartsList = Collections.unmodifiableList(new ArrayList<MPart>(
+ dirtyParts));
+ Save[] decisions = promptToSave(dirtyPartsList);
+ for (Save decision : decisions) {
+ if (decision == Save.CANCEL) {
+ return false;
+ }
+ }
+
+ for (int i = 0; i < decisions.length; i++) {
+ if (decisions[i] == Save.YES) {
+ if (!save(dirtyPartsList.get(i), false)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ for (MPart dirtyPart : dirtyParts) {
+ if (!save(dirtyPart, false)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.e4.ui.workbench.modeling.ISaveHandler#promptToSave(org.eclipse.e4.ui.model.
+ * application.ui.basic.MPart)
+ */
+ public Save promptToSave(MPart dirtyPart) {
+ return Save.YES;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.e4.ui.workbench.modeling.ISaveHandler#promptToSave(java.util.Collection)
+ */
+ public Save[] promptToSave(Collection<MPart> dirtyParts) {
+ Save[] rc = new Save[dirtyParts.size()];
+ for (int i = 0; i < rc.length; i++) {
+ rc[i] = Save.YES;
+ }
+ return rc;
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/workbench/modeling/ISaveHandler.java b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/workbench/modeling/ISaveHandler.java
index 5be71996d6f..5778847d170 100644
--- a/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/workbench/modeling/ISaveHandler.java
+++ b/bundles/org.eclipse.e4.ui.workbench/src/org/eclipse/e4/ui/workbench/modeling/ISaveHandler.java
@@ -20,6 +20,10 @@ public interface ISaveHandler {
YES, NO, CANCEL
}
+ public boolean save(MPart dirtyPart, boolean confirm);
+
+ public boolean saveParts(Collection<MPart> dirtyParts, boolean confirm);
+
public Save promptToSave(MPart dirtyPart);
public Save[] promptToSave(Collection<MPart> dirtyParts);
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/SaveAction.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/SaveAction.java
index e677c6f1c4b..677b3fa1830 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/SaveAction.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/SaveAction.java
@@ -17,6 +17,7 @@ import org.eclipse.ui.ISaveablesSource;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchCommandConstants;
import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
/**
@@ -65,9 +66,15 @@ public class SaveAction extends BaseSaveAction implements IBackgroundSaveListene
*/
ISaveablePart saveView = getSaveableView();
if (saveView != null) {
- ((WorkbenchPage) getActivePart().getSite().getPage()).saveSaveable(saveView, false,
- false);
- return;
+ IWorkbenchPart activePart = getActivePart();
+ WorkbenchPage workbenchPage;
+ if (activePart != null) {
+ workbenchPage = (WorkbenchPage) activePart.getSite().getPage();
+ } else {
+ workbenchPage = (WorkbenchPage) getActivePage();
+ }
+ workbenchPage.saveSaveable(saveView, activePart, false, false);
+ return;
}
IEditorPart part = getActiveEditor();
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/SaveableHelper.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/SaveableHelper.java
index d524c078971..1f753a91d8a 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/SaveableHelper.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/SaveableHelper.java
@@ -17,7 +17,6 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
-
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
@@ -183,20 +182,23 @@ public class SaveableHelper {
public void run(IProgressMonitor monitor) {
IProgressMonitor monitorWrap = new EventLoopProgressMonitor(monitor);
monitorWrap.beginTask(WorkbenchMessages.Save, dirtyModels.size());
- for (Iterator i = dirtyModels.iterator(); i.hasNext();) {
- Saveable model = (Saveable) i.next();
- // handle case where this model got saved as a result of saving another
- if (!model.isDirty()) {
- monitor.worked(1);
- continue;
- }
- doSaveModel(model, new SubProgressMonitor(monitorWrap, 1),
- window, confirm);
- if (monitor.isCanceled()) {
- break;
+ try {
+ for (Iterator i = dirtyModels.iterator(); i.hasNext();) {
+ Saveable model = (Saveable) i.next();
+ // handle case where this model got saved as a result of
+ // saving another
+ if (!model.isDirty()) {
+ monitor.worked(1);
+ continue;
+ }
+ doSaveModel(model, new SubProgressMonitor(monitorWrap, 1), window, confirm);
+ if (monitor.isCanceled()) {
+ break;
+ }
}
+ } finally {
+ monitorWrap.done();
}
- monitorWrap.done();
}
};
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/Workbench.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/Workbench.java
index b224db2bf99..c8f2473b5d5 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/Workbench.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/Workbench.java
@@ -1139,7 +1139,7 @@ public final class Workbench extends EventManager implements IWorkbench {
for (IWorkbenchWindow window : getWorkbenchWindows()) {
IWorkbenchPage page = window.getActivePage();
if (page != null) {
- if (!((WorkbenchPage) page).saveAllEditors(confirm, closing)) {
+ if (!((WorkbenchPage) page).saveAllEditors(confirm, closing, false)) {
return false;
}
}
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java
index c7c5ee63555..8fff9f744b2 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchPage.java
@@ -22,6 +22,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.ListIterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -31,8 +32,10 @@ import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
@@ -62,22 +65,27 @@ import org.eclipse.e4.ui.workbench.UIEvents;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState;
-import org.eclipse.e4.ui.workbench.modeling.ISaveHandler;
-import org.eclipse.e4.ui.workbench.modeling.ISaveHandler.Save;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IPageChangeProvider;
import org.eclipse.jface.dialogs.IPageChangedListener;
+import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.PageChangedEvent;
import org.eclipse.jface.internal.provisional.action.ICoolBarManager2;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.window.IShellProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTarget;
@@ -106,7 +114,9 @@ import org.eclipse.ui.IPerspectiveFactory;
import org.eclipse.ui.IPerspectiveRegistry;
import org.eclipse.ui.IReusableEditor;
import org.eclipse.ui.ISaveablePart;
+import org.eclipse.ui.ISaveablePart2;
import org.eclipse.ui.ISaveablesLifecycleListener;
+import org.eclipse.ui.ISaveablesSource;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISelectionService;
import org.eclipse.ui.IShowEditorInput;
@@ -123,10 +133,13 @@ import org.eclipse.ui.IWorkingSetManager;
import org.eclipse.ui.MultiPartInitException;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.Saveable;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.XMLMemento;
import org.eclipse.ui.contexts.IContextService;
+import org.eclipse.ui.dialogs.ListSelectionDialog;
import org.eclipse.ui.internal.dialogs.CustomizePerspectiveDialog;
+import org.eclipse.ui.internal.dialogs.EventLoopProgressMonitor;
import org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor;
import org.eclipse.ui.internal.e4.compatibility.CompatibilityPart;
import org.eclipse.ui.internal.e4.compatibility.CompatibilityView;
@@ -147,6 +160,7 @@ import org.eclipse.ui.internal.tweaklets.TabBehaviour;
import org.eclipse.ui.internal.tweaklets.Tweaklets;
import org.eclipse.ui.internal.util.Util;
import org.eclipse.ui.model.IWorkbenchAdapter;
+import org.eclipse.ui.model.WorkbenchPartLabelProvider;
import org.eclipse.ui.part.IShowInSource;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.views.IStickyViewDescriptor;
@@ -1437,7 +1451,7 @@ public class WorkbenchPage extends CompatibleWorkbenchPage implements
if (save) {
if (workbenchPart instanceof ISaveablePart) {
ISaveablePart saveablePart = (ISaveablePart) workbenchPart;
- if (!saveSaveable(saveablePart, confirm, true)) {
+ if (!saveSaveable(saveablePart, workbenchPart, confirm, true)) {
return false;
}
}
@@ -1519,6 +1533,7 @@ public class WorkbenchPage extends CompatibleWorkbenchPage implements
// check to ensure this perspective actually exists in this window
if (persp != null) {
if (saveParts) {
+ List<IWorkbenchPart> partsToSave = new ArrayList<IWorkbenchPart>();
// retrieve all parts under the specified perspective
List<MPart> parts = modelService.findElements(persp, null, MPart.class, null);
if (!parts.isEmpty()) {
@@ -1543,6 +1558,8 @@ public class WorkbenchPage extends CompatibleWorkbenchPage implements
if (!((ISaveablePart) workbenchPart).isSaveOnCloseNeeded()) {
part.setDirty(false);
it.remove();
+ } else {
+ partsToSave.add(workbenchPart);
}
}
}
@@ -1551,32 +1568,10 @@ public class WorkbenchPage extends CompatibleWorkbenchPage implements
}
}
- if (!parts.isEmpty()) {
- ISaveHandler saveHandler = persp.getContext().get(ISaveHandler.class);
- if (parts.size() == 1) {
- Save responses = saveHandler.promptToSave(parts.get(0));
- switch (responses) {
- case CANCEL:
- return;
- case NO:
- break;
- case YES:
- partService.savePart(parts.get(0), false);
- break;
- }
- } else {
- Save[] responses = saveHandler.promptToSave(parts);
- for (Save response : responses) {
- if (response == Save.CANCEL) {
- return;
- }
- }
-
- for (int i = 0; i < responses.length; i++) {
- if (responses[i] == Save.YES) {
- partService.savePart(parts.get(i), false);
- }
- }
+ if (!partsToSave.isEmpty()) {
+ if (!saveAll(partsToSave, true, true, false, legacyWindow, legacyWindow)) {
+ // user cancel
+ return;
}
}
}
@@ -1655,7 +1650,7 @@ public class WorkbenchPage extends CompatibleWorkbenchPage implements
}
private boolean close(boolean save, boolean unsetPage) {
- if (save && !saveAllEditors(true, true)) {
+ if (save && !saveAllEditors(true, true, true)) {
return false;
}
@@ -3178,6 +3173,7 @@ public class WorkbenchPage extends CompatibleWorkbenchPage implements
}
List<MPart> dirtyParts = new ArrayList<MPart>();
+ List<IWorkbenchPart> partsToSave = new ArrayList<IWorkbenchPart>();
// iterate over the list of parts to find dirty parts
for (MPart currentPart : perspectiveParts) {
if (currentPart.isDirty()) {
@@ -3185,63 +3181,40 @@ public class WorkbenchPage extends CompatibleWorkbenchPage implements
if (object == null) {
continue;
} else if (object instanceof CompatibilityPart) {
- CompatibilityPart compatibilityPart = (CompatibilityPart) object;
- if (!((ISaveablePart) compatibilityPart.getPart()).isSaveOnCloseNeeded()) {
+ IWorkbenchPart workbenchPart = ((CompatibilityPart) object).getPart();
+ if (!(workbenchPart instanceof ISaveablePart)
+ || !((ISaveablePart) workbenchPart).isSaveOnCloseNeeded()) {
continue;
}
+ partsToSave.add(workbenchPart);
}
dirtyParts.add(currentPart);
}
}
- if (!dirtyParts.isEmpty()) {
- ISaveHandler saveHandler = window.getContext().get(ISaveHandler.class);
- if (dirtyParts.size() == 1) {
- MPart part = dirtyParts.get(0);
- switch (saveHandler.promptToSave(part)) {
- case YES:
- partService.savePart(part, false);
- break;
- case NO:
- part.setDirty(false);
- // not saving this part, close it
- partService.hidePart(part);
- break;
- case CANCEL:
- // not going through with it, but we're done
- legacyWindow.firePerspectiveChanged(this, desc, CHANGE_RESET_COMPLETE);
- return;
- }
- } else {
- Save[] promptToSave = saveHandler.promptToSave(dirtyParts);
- for (Save save : promptToSave) {
- if (save == ISaveHandler.Save.CANCEL) {
- // not going through with it, but we're done
- legacyWindow.firePerspectiveChanged(this, desc, CHANGE_RESET_COMPLETE);
- return;
- }
- }
-
- for (int i = 0; i < promptToSave.length; i++) {
- switch (promptToSave[i]) {
- case NO:
- dirtyParts.get(i).setDirty(false);
- // not saving this part, close it
- partService.hidePart(dirtyParts.get(i));
- break;
- case YES:
- partService.savePart(dirtyParts.get(i), false);
- break;
- case CANCEL:
- break;
- }
- }
+ SaveablesList saveablesList = null;
+ Object postCloseInfo = null;
+ if (partsToSave.size() > 0) {
+ saveablesList = (SaveablesList) getWorkbenchWindow().getService(
+ ISaveablesLifecycleListener.class);
+ postCloseInfo = saveablesList.preCloseParts(partsToSave, true,
+ this.getWorkbenchWindow());
+ if (postCloseInfo == null) {
+ // cancel
+ // We're not going through with the reset, so it is
+ // complete.
+ legacyWindow.firePerspectiveChanged(this, desc, CHANGE_RESET_COMPLETE);
+ return;
}
}
modelService.resetPerspectiveModel(persp, window);
+ if (saveablesList != null) {
+ saveablesList.postClose(postCloseInfo);
+ }
+
boolean revert = false;
if (desc instanceof PerspectiveDescriptor) {
PerspectiveDescriptor perspectiveDescriptor = (PerspectiveDescriptor) desc;
@@ -3350,59 +3323,355 @@ public class WorkbenchPage extends CompatibleWorkbenchPage implements
* See IWorkbenchPage
*/
public boolean saveAllEditors(boolean confirm) {
- return saveAllEditors(confirm, false);
+ return saveAllEditors(confirm, false, false);
}
- boolean saveAllEditors(boolean confirm, boolean closing) {
- List<MPart> dirtyParts = new ArrayList<MPart>();
- // find all the dirty parts in this window
- for (MPart currentPart : modelService.findElements(window, null, MPart.class, null)) {
- if (currentPart.isDirty()) {
- Object object = currentPart.getObject();
- if (object == null) {
- continue;
- } else if (object instanceof CompatibilityPart) {
- CompatibilityPart compatibilityPart = (CompatibilityPart) object;
- if (closing
- && !((ISaveablePart) compatibilityPart.getPart()).isSaveOnCloseNeeded()) {
- continue;
- }
+ public ISaveablePart[] getDirtyParts() {
+ List result = new ArrayList(3);
+ IWorkbenchPartReference[] allParts = getSortedParts();
+ for (int i = 0; i < allParts.length; i++) {
+ IWorkbenchPartReference reference = allParts[i];
+
+ IWorkbenchPart part = reference.getPart(false);
+ if (part != null && part instanceof ISaveablePart) {
+ ISaveablePart saveable = (ISaveablePart) part;
+ if (saveable.isDirty()) {
+ result.add(saveable);
}
-
- dirtyParts.add(currentPart);
}
}
- if (!dirtyParts.isEmpty()) {
- if (confirm) {
- if (dirtyParts.size() == 1) {
- return partService.savePart(dirtyParts.get(0), true);
+ return (ISaveablePart[]) result.toArray(new ISaveablePart[result.size()]);
+ }
+
+ public boolean saveAllEditors(boolean confirm, boolean closing, boolean addNonPartSources) {
+ ISaveablePart[] parts = getDirtyParts();
+ if (parts.length == 0) {
+ return true;
+ }
+ // saveAll below expects a mutable list
+ List dirtyParts = new ArrayList(parts.length);
+ for (int i = 0; i < parts.length; i++) {
+ dirtyParts.add(parts[i]);
+ }
+
+ // If confirmation is required ..
+ return saveAll(dirtyParts, confirm, closing, addNonPartSources, legacyWindow, legacyWindow);
+ }
+
+ public static boolean saveAll(List dirtyParts, final boolean confirm, final boolean closing,
+ boolean addNonPartSources, final IRunnableContext runnableContext,
+ final IShellProvider shellProvider) {
+ // clone the input list
+ dirtyParts = new ArrayList(dirtyParts);
+
+ if (closing) {
+ // if the parts are going to be closed, then we only save those that
+ // need to be saved when closed, see bug 272070
+ for (Iterator it = dirtyParts.iterator(); it.hasNext();) {
+ ISaveablePart saveablePart = (ISaveablePart) it.next();
+ if (!saveablePart.isSaveOnCloseNeeded()) {
+ it.remove();
}
+ }
+ }
- ISaveHandler saveHandler = window.getContext().get(ISaveHandler.class);
- Save[] promptToSave = saveHandler.promptToSave(dirtyParts);
- for (Save save : promptToSave) {
- if (save == ISaveHandler.Save.CANCEL) {
+ List modelsToSave;
+ if (confirm) {
+ boolean saveable2Processed = false;
+ // Process all parts that implement ISaveablePart2.
+ // These parts are removed from the list after saving
+ // them. 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.
+ ListIterator listIterator = dirtyParts.listIterator();
+
+ WorkbenchPage currentPage = null;
+ Perspective currentPageOriginalPerspective = null;
+ while (listIterator.hasNext()) {
+ IWorkbenchPart part = (IWorkbenchPart) listIterator.next();
+ if (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 (confirm) {
+ // 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(), confirm);
+ 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 false;
+ } else if (choice != ISaveablePart2.DEFAULT) {
+ saveable2Processed = true;
+ listIterator.remove();
}
}
+ }
- for (int i = 0; i < promptToSave.length; i++) {
- if (promptToSave[i] == Save.YES) {
- if (!partService.savePart(dirtyParts.get(i), false)) {
- return false;
- }
+ // try to restore the workbench to its previous state
+ if (currentPage != null && currentPageOriginalPerspective != null) {
+ if (!currentPageOriginalPerspective.equals(currentPage.getActivePerspective())) {
+ currentPage.setPerspective(currentPageOriginalPerspective.getDesc());
+ }
+ }
+
+ // if processing a ISaveablePart2 caused other parts to be
+ // saved, remove them from the list presented to the user.
+ if (saveable2Processed) {
+ listIterator = dirtyParts.listIterator();
+ while (listIterator.hasNext()) {
+ ISaveablePart part = (ISaveablePart) listIterator.next();
+ if (!part.isDirty()) {
+ listIterator.remove();
+ }
+ }
+ }
+
+ modelsToSave = convertToSaveables(dirtyParts, closing, addNonPartSources);
+
+ // If nothing to save, return.
+ if (modelsToSave.isEmpty()) {
+ return true;
+ }
+ boolean canceled = SaveableHelper.waitForBackgroundSaveJobs(modelsToSave);
+ if (canceled) {
+ return false;
+ }
+ // Use a simpler dialog if there's only one
+ if (modelsToSave.size() == 1) {
+ Saveable model = (Saveable) modelsToSave.get(0);
+ String message = NLS.bind(WorkbenchMessages.EditorManager_saveChangesQuestion,
+ model.getName());
+ // Show a dialog.
+ String[] buttons = new String[] { IDialogConstants.YES_LABEL,
+ IDialogConstants.NO_LABEL, IDialogConstants.CANCEL_LABEL };
+ MessageDialog d = new MessageDialog(shellProvider.getShell(),
+ WorkbenchMessages.Save_Resource, null, message, MessageDialog.QUESTION,
+ buttons, 0) {
+ protected int getShellStyle() {
+ return super.getShellStyle() | SWT.SHEET;
}
+ };
+
+ int choice = SaveableHelper.testGetAutomatedResponse();
+ if (SaveableHelper.testGetAutomatedResponse() == SaveableHelper.USER_RESPONSE) {
+ choice = d.open();
+ }
+
+ // Branch on the user choice.
+ // The choice id is based on the order of button labels
+ // above.
+ switch (choice) {
+ case ISaveablePart2.YES: // yes
+ break;
+ case ISaveablePart2.NO: // no
+ return true;
+ default:
+ case ISaveablePart2.CANCEL: // cancel
+ return false;
}
} else {
- for (MPart part : dirtyParts) {
- if (!partService.savePart(part, false)) {
+ ListSelectionDialog dlg = new ListSelectionDialog(shellProvider.getShell(),
+ modelsToSave, new ArrayContentProvider(), new WorkbenchPartLabelProvider(),
+ WorkbenchMessages.EditorManager_saveResourcesMessage) {
+ protected int getShellStyle() {
+ return super.getShellStyle() | SWT.SHEET;
+ }
+ };
+ dlg.setInitialSelections(modelsToSave.toArray());
+ dlg.setTitle(WorkbenchMessages.EditorManager_saveResourcesTitle);
+
+ // this "if" statement aids in testing.
+ if (SaveableHelper.testGetAutomatedResponse() == SaveableHelper.USER_RESPONSE) {
+ int result = dlg.open();
+ // Just return false to prevent the operation continuing
+ if (result == IDialogConstants.CANCEL_ID) {
return false;
}
+
+ modelsToSave = Arrays.asList(dlg.getResult());
}
}
+ } else {
+ modelsToSave = convertToSaveables(dirtyParts, closing, addNonPartSources);
}
- return true;
+
+ // If the editor list is empty return.
+ if (modelsToSave.isEmpty()) {
+ return true;
+ }
+
+ // Create save block.
+ final List finalModels = modelsToSave;
+ IRunnableWithProgress progressOp = new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) {
+ IProgressMonitor monitorWrap = new EventLoopProgressMonitor(monitor);
+ monitorWrap.beginTask(WorkbenchMessages.Saving_Modifications, finalModels.size());
+ for (Iterator i = finalModels.iterator(); i.hasNext();) {
+ Saveable model = (Saveable) i.next();
+ // handle case where this model got saved as a result of
+ // saving another
+ if (!model.isDirty()) {
+ monitor.worked(1);
+ continue;
+ }
+ SaveableHelper.doSaveModel(model, new SubProgressMonitor(monitorWrap, 1),
+ shellProvider, closing || confirm);
+ if (monitorWrap.isCanceled()) {
+ break;
+ }
+ }
+ monitorWrap.done();
+ }
+ };
+
+ // Do the save.
+ return SaveableHelper.runProgressMonitorOperation(WorkbenchMessages.Save_All, progressOp,
+ runnableContext, shellProvider);
+ }
+
+ /**
+ * For each part (view or editor) in the given list, attempts to convert it
+ * to one or more saveable models. Duplicate models are removed. If closing
+ * is true, then models that will remain open in parts other than the given
+ * parts are removed.
+ *
+ * @param parts
+ * the parts (list of IViewPart or IEditorPart)
+ * @param closing
+ * whether the parts are being closed
+ * @param addNonPartSources
+ * whether non-part sources should be added (true for the Save
+ * All action, see bug 139004)
+ * @return the dirty models
+ */
+ private static List convertToSaveables(List parts, boolean closing, boolean addNonPartSources) {
+ ArrayList result = new ArrayList();
+ HashSet seen = new HashSet();
+ for (Iterator i = parts.iterator(); i.hasNext();) {
+ IWorkbenchPart part = (IWorkbenchPart) i.next();
+ Saveable[] saveables = getSaveables(part);
+ for (int j = 0; j < saveables.length; j++) {
+ Saveable saveable = saveables[j];
+ if (saveable.isDirty() && !seen.contains(saveable)) {
+ seen.add(saveable);
+ if (!closing
+ || closingLastPartShowingModel(saveable, parts, part.getSite()
+ .getPage())) {
+ result.add(saveable);
+ }
+ }
+ }
+ }
+ if (addNonPartSources) {
+ SaveablesList saveablesList = (SaveablesList) PlatformUI.getWorkbench().getService(
+ ISaveablesLifecycleListener.class);
+ ISaveablesSource[] nonPartSources = saveablesList.getNonPartSources();
+ for (int i = 0; i < nonPartSources.length; i++) {
+ Saveable[] saveables = nonPartSources[i].getSaveables();
+ for (int j = 0; j < saveables.length; j++) {
+ Saveable saveable = saveables[j];
+ if (saveable.isDirty() && !seen.contains(saveable)) {
+ seen.add(saveable);
+ result.add(saveable);
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns the saveable models provided by the given part. If the part does
+ * not provide any models, a default model is returned representing the
+ * part.
+ *
+ * @param part
+ * the workbench part
+ * @return the saveable models
+ */
+ private static Saveable[] getSaveables(IWorkbenchPart part) {
+ if (part instanceof ISaveablesSource) {
+ ISaveablesSource source = (ISaveablesSource) part;
+ return source.getSaveables();
+ }
+ return new Saveable[] { new DefaultSaveable(part) };
+ }
+
+ /**
+ * Returns true if, in the given page, no more parts will reference the
+ * given model if the given parts are closed.
+ *
+ * @param model
+ * the model
+ * @param closingParts
+ * the parts being closed (list of IViewPart or IEditorPart)
+ * @param page
+ * the page
+ * @return <code>true</code> if no more parts in the page will reference the
+ * given model, <code>false</code> otherwise
+ */
+ private static boolean closingLastPartShowingModel(Saveable model, List closingParts,
+ IWorkbenchPage page) {
+ HashSet closingPartsWithSameModel = new HashSet();
+ for (Iterator i = closingParts.iterator(); i.hasNext();) {
+ IWorkbenchPart part = (IWorkbenchPart) i.next();
+ Saveable[] models = getSaveables(part);
+ if (Arrays.asList(models).contains(model)) {
+ closingPartsWithSameModel.add(part);
+ }
+ }
+ IWorkbenchPartReference[] pagePartRefs = ((WorkbenchPage) page).getSortedParts();
+ HashSet pagePartsWithSameModels = new HashSet();
+ for (int i = 0; i < pagePartRefs.length; i++) {
+ IWorkbenchPartReference partRef = pagePartRefs[i];
+ IWorkbenchPart part = partRef.getPart(false);
+ if (part != null) {
+ Saveable[] models = getSaveables(part);
+ if (Arrays.asList(models).contains(model)) {
+ pagePartsWithSameModels.add(part);
+ }
+ }
+ }
+ for (Iterator i = closingPartsWithSameModel.iterator(); i.hasNext();) {
+ IWorkbenchPart part = (IWorkbenchPart) i.next();
+ pagePartsWithSameModels.remove(part);
+ }
+ return pagePartsWithSameModels.isEmpty();
}
/**
@@ -3422,24 +3691,9 @@ public class WorkbenchPage extends CompatibleWorkbenchPage implements
* <code>false</code> otherwise
* @see ISaveablePart#isSaveOnCloseNeeded()
*/
- public boolean saveSaveable(ISaveablePart saveable, boolean confirm, boolean closing) {
- MPart part = findPart((IWorkbenchPart) saveable);
- if (part != null) {
- if (saveable.isDirty()) {
- if (closing) {
- if (saveable.isSaveOnCloseNeeded()) {
- return partService.savePart(part, confirm);
- }
- // mark the part as no longer being dirty so it can be
- // closed
- part.setDirty(false);
- } else {
- return partService.savePart(part, confirm);
- }
- }
- return true;
- }
- return false;
+ public boolean saveSaveable(ISaveablePart saveable, IWorkbenchPart part, boolean confirm,
+ boolean closing) {
+ return SaveableHelper.savePart(saveable, part, legacyWindow, confirm);
}
/**
@@ -3452,7 +3706,7 @@ public class WorkbenchPage extends CompatibleWorkbenchPage implements
* if the user cancels the command
*/
public boolean saveEditor(IEditorPart editor, boolean confirm) {
- return saveSaveable(editor, confirm, false);
+ return saveSaveable(editor, editor, confirm, false);
}
/*
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java
index e780a8c764d..067f47998db 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/WorkbenchWindow.java
@@ -42,7 +42,10 @@ import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.contexts.RunAndTrack;
import org.eclipse.e4.core.di.InjectionException;
+import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.services.events.IEventBroker;
+import org.eclipse.e4.core.services.log.Logger;
+import org.eclipse.e4.ui.internal.workbench.PartServiceSaveHandler;
import org.eclipse.e4.ui.internal.workbench.URIHelper;
import org.eclipse.e4.ui.internal.workbench.renderers.swt.IUpdateService;
import org.eclipse.e4.ui.model.application.MApplication;
@@ -205,6 +208,10 @@ public class WorkbenchWindow implements IWorkbenchWindow {
private IEventBroker eventBroker;
@Inject
+ @Optional
+ private Logger logger;
+
+ @Inject
private IExtensionRegistry extensionRegistry;
private WorkbenchPage page;
@@ -447,7 +454,7 @@ public class WorkbenchWindow implements IWorkbenchWindow {
});
final ISaveHandler defaultSaveHandler = windowContext.get(ISaveHandler.class);
- windowContext.set(ISaveHandler.class, new ISaveHandler() {
+ final PartServiceSaveHandler localSaveHandler = new PartServiceSaveHandler() {
public Save promptToSave(MPart dirtyPart) {
Object object = dirtyPart.getObject();
if (object instanceof CompatibilityPart) {
@@ -493,7 +500,39 @@ public class WorkbenchWindow implements IWorkbenchWindow {
}
return retSaves;
}
- });
+
+ public boolean save(MPart dirtyPart, boolean confirm) {
+ Object object = dirtyPart.getObject();
+ if (object instanceof CompatibilityPart) {
+ IWorkbenchPart workbenchPart = ((CompatibilityPart) object).getPart();
+ if (workbenchPart instanceof ISaveablePart) {
+ ISaveablePart saveablePart = (ISaveablePart) workbenchPart;
+ return page.saveSaveable(saveablePart, workbenchPart, confirm, false);
+ }
+ }
+ return super.save(dirtyPart, confirm);
+ }
+
+ public boolean saveParts(Collection<MPart> dirtyParts, boolean confirm) {
+ ArrayList<ISaveablePart> saveables = new ArrayList<ISaveablePart>();
+ for (MPart part : dirtyParts) {
+ Object object = part.getObject();
+ if (object instanceof CompatibilityPart) {
+ IWorkbenchPart workbenchPart = ((CompatibilityPart) object).getPart();
+ if (workbenchPart instanceof ISaveablePart) {
+ saveables.add((ISaveablePart) workbenchPart);
+ }
+ }
+ }
+ if (saveables.isEmpty()) {
+ return super.saveParts(dirtyParts, confirm);
+ }
+ return WorkbenchPage.saveAll(saveables, confirm, false, true, WorkbenchWindow.this,
+ WorkbenchWindow.this);
+ }
+ };
+ localSaveHandler.logger = logger;
+ windowContext.set(ISaveHandler.class, localSaveHandler);
windowContext.set(IWorkbenchWindow.class.getName(), this);
windowContext.set(IPageService.class, this);
@@ -1561,7 +1600,7 @@ public class WorkbenchWindow implements IWorkbenchWindow {
if (!getWorkbenchImpl().isClosing()) {
IWorkbenchPage page = getActivePage();
if (page != null) {
- return ((WorkbenchPage) page).saveAllEditors(true, true);
+ return ((WorkbenchPage) page).saveAllEditors(true, true, true);
}
}
return true;
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/handlers/SaveAllHandler.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/handlers/SaveAllHandler.java
new file mode 100644
index 00000000000..e12d3cfe028
--- /dev/null
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/handlers/SaveAllHandler.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2013 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.ui.internal.handlers;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.expressions.EvaluationResult;
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.ui.ISaveablesLifecycleListener;
+import org.eclipse.ui.ISaveablesSource;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.Saveable;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.ui.internal.InternalHandlerUtil;
+import org.eclipse.ui.internal.SaveablesList;
+import org.eclipse.ui.internal.WorkbenchPage;
+
+/**
+ * Saves all active editors
+ * <p>
+ * Replacement for SaveAllAction
+ * </p>
+ *
+ * @since 3.7
+ *
+ */
+public class SaveAllHandler extends AbstractSaveHandler {
+
+ public SaveAllHandler() {
+ registerEnablement();
+ }
+
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+ IWorkbenchWindow window = HandlerUtil
+ .getActiveWorkbenchWindowChecked(event);
+ IWorkbenchPage page = window.getActivePage();
+ if (page != null) {
+ ((WorkbenchPage) page).saveAllEditors(false, false, true);
+ }
+
+ return null;
+ }
+
+ protected EvaluationResult evaluate(IEvaluationContext context) {
+
+ IWorkbenchWindow window = InternalHandlerUtil.getActiveWorkbenchWindow(context);
+ // no window? not active
+ if (window == null)
+ return EvaluationResult.FALSE;
+ WorkbenchPage page = (WorkbenchPage) window.getActivePage();
+
+ // no page? not active
+ if (page == null)
+ return EvaluationResult.FALSE;
+
+ // if at least one dirty part, then we are active
+ if (page.getDirtyParts().length > 0)
+ return EvaluationResult.TRUE;
+
+ // Since Save All also saves saveables from non-part sources,
+ // look if any such saveables exist and are dirty.
+ SaveablesList saveablesList = (SaveablesList) window.getWorkbench().getService(
+ ISaveablesLifecycleListener.class);
+ ISaveablesSource[] nonPartSources = saveablesList.getNonPartSources();
+ for (int i = 0; i < nonPartSources.length; i++) {
+ Saveable[] saveables = nonPartSources[i].getSaveables();
+ for (int j = 0; j < saveables.length; j++) {
+ if (saveables[j].isDirty()) {
+ return EvaluationResult.TRUE;
+ }
+ }
+ }
+
+ // if nothing, then we are not active
+ return EvaluationResult.FALSE;
+ }
+
+}
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/handlers/SaveHandler.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/handlers/SaveHandler.java
new file mode 100644
index 00000000000..a57fad52d86
--- /dev/null
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/handlers/SaveHandler.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2013 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.ui.internal.handlers;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.expressions.EvaluationResult;
+import org.eclipse.core.expressions.IEvaluationContext;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.ISaveablePart;
+import org.eclipse.ui.ISaveablesSource;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.ui.internal.InternalHandlerUtil;
+import org.eclipse.ui.internal.SaveableHelper;
+import org.eclipse.ui.internal.WorkbenchPage;
+
+/**
+ * <p>
+ * Replacement for SaveAction
+ * </p>
+ *
+ * @since 3.7
+ *
+ */
+public class SaveHandler extends AbstractSaveHandler {
+
+ public SaveHandler() {
+ registerEnablement();
+ }
+
+ public Object execute(ExecutionEvent event) {
+
+ ISaveablePart saveablePart = getSaveablePart(event);
+
+ // no saveable
+ if (saveablePart == null)
+ return null;
+
+ // if editor
+ if (saveablePart instanceof IEditorPart) {
+ IEditorPart editorPart = (IEditorPart) saveablePart;
+ IWorkbenchPage page = editorPart.getSite().getPage();
+ page.saveEditor(editorPart, false);
+ return null;
+ }
+
+ // if view
+ IWorkbenchPart activePart = HandlerUtil.getActivePart(event);
+ WorkbenchPage page = (WorkbenchPage) activePart.getSite().getPage();
+ page.saveSaveable(saveablePart, activePart, false, false);
+
+ return null;
+
+ }
+
+ protected EvaluationResult evaluate(IEvaluationContext context) {
+
+ IWorkbenchWindow window = InternalHandlerUtil.getActiveWorkbenchWindow(context);
+ // no window? not active
+ if (window == null)
+ return EvaluationResult.FALSE;
+ WorkbenchPage page = (WorkbenchPage) window.getActivePage();
+
+ // no page? not active
+ if (page == null)
+ return EvaluationResult.FALSE;
+
+ // get saveable part
+ ISaveablePart saveablePart = getSaveablePart(context);
+ if (saveablePart == null)
+ return EvaluationResult.FALSE;
+
+ if (saveablePart instanceof ISaveablesSource) {
+ ISaveablesSource modelSource = (ISaveablesSource) saveablePart;
+ if (SaveableHelper.needsSave(modelSource))
+ return EvaluationResult.TRUE;
+ return EvaluationResult.FALSE;
+ }
+
+ if (saveablePart != null && saveablePart.isDirty())
+ return EvaluationResult.TRUE;
+
+ return EvaluationResult.FALSE;
+ }
+}
diff --git a/tests/org.eclipse.e4.ui.tests/src/org/eclipse/e4/ui/tests/application/EPartServiceTest.java b/tests/org.eclipse.e4.ui.tests/src/org/eclipse/e4/ui/tests/application/EPartServiceTest.java
index 1089b7a1913..c0cde535e5f 100644
--- a/tests/org.eclipse.e4.ui.tests/src/org/eclipse/e4/ui/tests/application/EPartServiceTest.java
+++ b/tests/org.eclipse.e4.ui.tests/src/org/eclipse/e4/ui/tests/application/EPartServiceTest.java
@@ -20,6 +20,7 @@ import org.eclipse.core.runtime.AssertionFailedException;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.e4.ui.internal.workbench.E4Workbench;
+import org.eclipse.e4.ui.internal.workbench.PartServiceSaveHandler;
import org.eclipse.e4.ui.internal.workbench.UIEventPublisher;
import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor;
import org.eclipse.e4.ui.model.application.ui.MElementContainer;
@@ -3786,7 +3787,7 @@ public class EPartServiceTest extends UITest {
editor.setThrowException(throwException);
window.getContext().set(ISaveHandler.class.getName(),
- new ISaveHandler() {
+ new PartServiceSaveHandler() {
public Save[] promptToSave(Collection<MPart> saveablePart) {
return null;
}
@@ -4111,7 +4112,7 @@ public class EPartServiceTest extends UITest {
editor2.setThrowException(throwException[1]);
window.getContext().set(ISaveHandler.class.getName(),
- new ISaveHandler() {
+ new PartServiceSaveHandler() {
public Save[] promptToSave(Collection<MPart> saveableParts) {
int index = 0;
Save[] prompt = new Save[saveableParts.size()];
@@ -10160,7 +10161,7 @@ public class EPartServiceTest extends UITest {
new UIEventPublisher(applicationContext));
applicationContext.set(ISaveHandler.class.getName(),
- new ISaveHandler() {
+ new PartServiceSaveHandler() {
public Save[] promptToSave(Collection<MPart> saveablePart) {
Save[] ret = new Save[saveablePart.size()];
Arrays.fill(ret, ISaveHandler.Save.YES);
@@ -10170,6 +10171,7 @@ public class EPartServiceTest extends UITest {
public Save promptToSave(MPart saveablePart) {
return ISaveHandler.Save.YES;
}
+
});
}
diff --git a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/api/APITestUtils.java b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/api/APITestUtils.java
index f47bd3eb0b4..c2822d8ca0d 100644
--- a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/api/APITestUtils.java
+++ b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/api/APITestUtils.java
@@ -18,6 +18,7 @@ import java.util.List;
import java.util.Map;
import org.eclipse.e4.core.contexts.IEclipseContext;
+import org.eclipse.e4.ui.internal.workbench.PartServiceSaveHandler;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.MUIElement;
import org.eclipse.e4.ui.model.application.ui.advanced.MPlaceholder;
@@ -27,6 +28,7 @@ import org.eclipse.e4.ui.workbench.modeling.ISaveHandler;
import org.eclipse.ui.ISaveablePart2;
import org.eclipse.ui.IViewReference;
import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.internal.SaveableHelper;
import org.eclipse.ui.internal.Workbench;
import org.eclipse.ui.internal.WorkbenchPartReference;
@@ -34,7 +36,7 @@ public class APITestUtils {
private static Map<IEclipseContext, ISaveHandler> originalHandlers = new HashMap<IEclipseContext, ISaveHandler>();
private static TestSaveHandler testSaveHandler = new TestSaveHandler();
- static class TestSaveHandler implements ISaveHandler {
+ static class TestSaveHandler extends PartServiceSaveHandler {
private int response;
public void setResponse(int response) {
@@ -58,6 +60,7 @@ public class APITestUtils {
Arrays.fill(prompt, save);
return prompt;
}
+
}
public static boolean isFastView(IViewReference ref) {
@@ -79,6 +82,7 @@ public class APITestUtils {
}
public static void saveableHelperSetAutomatedResponse(final int response) {
+ SaveableHelper.testSetAutomatedResponse(response);
Workbench workbench = (Workbench) PlatformUI.getWorkbench();
MApplication application = workbench.getApplication();

Back to the top