Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 226618 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/mylyn/internal/context/ui/ContextUiPlugin.java (-2 / +73 lines)
Lines 11-16 Link Here
11
11
12
package org.eclipse.mylyn.internal.context.ui;
12
package org.eclipse.mylyn.internal.context.ui;
13
13
14
import java.io.File;
15
import java.io.StringReader;
14
import java.util.ArrayList;
16
import java.util.ArrayList;
15
import java.util.Collections;
17
import java.util.Collections;
16
import java.util.HashMap;
18
import java.util.HashMap;
Lines 27-35 Link Here
27
import org.eclipse.core.runtime.IExtension;
29
import org.eclipse.core.runtime.IExtension;
28
import org.eclipse.core.runtime.IExtensionPoint;
30
import org.eclipse.core.runtime.IExtensionPoint;
29
import org.eclipse.core.runtime.IExtensionRegistry;
31
import org.eclipse.core.runtime.IExtensionRegistry;
32
import org.eclipse.core.runtime.IPath;
30
import org.eclipse.core.runtime.IStatus;
33
import org.eclipse.core.runtime.IStatus;
31
import org.eclipse.core.runtime.Platform;
34
import org.eclipse.core.runtime.Platform;
32
import org.eclipse.core.runtime.Status;
35
import org.eclipse.core.runtime.Status;
36
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
37
import org.eclipse.core.runtime.preferences.InstanceScope;
33
import org.eclipse.jface.dialogs.MessageDialog;
38
import org.eclipse.jface.dialogs.MessageDialog;
34
import org.eclipse.jface.preference.IPreferenceStore;
39
import org.eclipse.jface.preference.IPreferenceStore;
35
import org.eclipse.jface.resource.ImageDescriptor;
40
import org.eclipse.jface.resource.ImageDescriptor;
Lines 47-52 Link Here
47
import org.eclipse.mylyn.context.core.IInteractionRelation;
52
import org.eclipse.mylyn.context.core.IInteractionRelation;
48
import org.eclipse.mylyn.context.ui.AbstractContextUiBridge;
53
import org.eclipse.mylyn.context.ui.AbstractContextUiBridge;
49
import org.eclipse.mylyn.context.ui.IContextUiStartup;
54
import org.eclipse.mylyn.context.ui.IContextUiStartup;
55
import org.eclipse.mylyn.internal.context.core.InteractionContext;
50
import org.eclipse.mylyn.internal.monitor.ui.MonitorUiPlugin;
56
import org.eclipse.mylyn.internal.monitor.ui.MonitorUiPlugin;
51
import org.eclipse.mylyn.monitor.ui.MonitorUi;
57
import org.eclipse.mylyn.monitor.ui.MonitorUi;
52
import org.eclipse.mylyn.tasks.core.ITask;
58
import org.eclipse.mylyn.tasks.core.ITask;
Lines 57-70 Link Here
57
import org.eclipse.swt.graphics.Image;
63
import org.eclipse.swt.graphics.Image;
58
import org.eclipse.ui.IEditorInput;
64
import org.eclipse.ui.IEditorInput;
59
import org.eclipse.ui.IEditorPart;
65
import org.eclipse.ui.IEditorPart;
66
import org.eclipse.ui.IMemento;
60
import org.eclipse.ui.IViewPart;
67
import org.eclipse.ui.IViewPart;
61
import org.eclipse.ui.IViewReference;
68
import org.eclipse.ui.IViewReference;
62
import org.eclipse.ui.IWorkbench;
69
import org.eclipse.ui.IWorkbench;
63
import org.eclipse.ui.IWorkbenchWindow;
70
import org.eclipse.ui.IWorkbenchWindow;
64
import org.eclipse.ui.PlatformUI;
71
import org.eclipse.ui.PlatformUI;
72
import org.eclipse.ui.WorkbenchException;
73
import org.eclipse.ui.XMLMemento;
65
import org.eclipse.ui.internal.WorkbenchPlugin;
74
import org.eclipse.ui.internal.WorkbenchPlugin;
66
import org.eclipse.ui.plugin.AbstractUIPlugin;
75
import org.eclipse.ui.plugin.AbstractUIPlugin;
76
import org.eclipse.ui.preferences.ScopedPreferenceStore;
67
import org.osgi.framework.BundleContext;
77
import org.osgi.framework.BundleContext;
78
import org.osgi.service.prefs.BackingStoreException;
68
79
69
/**
80
/**
70
 * Main entry point for the Context UI.
81
 * Main entry point for the Context UI.
Lines 75-80 Link Here
75
 */
86
 */
76
public class ContextUiPlugin extends AbstractUIPlugin {
87
public class ContextUiPlugin extends AbstractUIPlugin {
77
88
89
	private static final String EDITOR_MEMNTO_PREFS_PREFIX = "editors.task."; //$NON-NLS-1$
90
78
	public static final String ID_PLUGIN = "org.eclipse.mylyn.context.ui"; //$NON-NLS-1$
91
	public static final String ID_PLUGIN = "org.eclipse.mylyn.context.ui"; //$NON-NLS-1$
79
92
80
	private class ContextActivationListener extends AbstractContextListener {
93
	private class ContextActivationListener extends AbstractContextListener {
Lines 208-213 Link Here
208
221
209
	private ContextEditorManager editorManager;
222
	private ContextEditorManager editorManager;
210
223
224
	private ContextMementoManager mementoManager;
225
211
	public ContextUiPlugin() {
226
	public ContextUiPlugin() {
212
		INSTANCE = this;
227
		INSTANCE = this;
213
	}
228
	}
Lines 256-263 Link Here
256
			MonitorUi.addWindowPerspectiveListener(perspectiveManager);
271
			MonitorUi.addWindowPerspectiveListener(perspectiveManager);
257
			TasksUi.getTaskActivityManager().addActivationListener(TASK_ACTIVATION_LISTENER);
272
			TasksUi.getTaskActivityManager().addActivationListener(TASK_ACTIVATION_LISTENER);
258
273
274
			mementoManager = new ContextMementoManager(ContextCore.getContextManager(), getContextMementoPath());
275
			mementoManager.start();
276
259
			editorManager = new ContextEditorManager();
277
			editorManager = new ContextEditorManager();
260
			ContextCore.getContextManager().addListener(editorManager);
278
			editorManager.start(ContextCore.getContextManager(), mementoManager);
279
280
			migrateContextMementos(mementoManager);
261
		} catch (Exception e) {
281
		} catch (Exception e) {
262
			StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, "Context UI initialization failed", //$NON-NLS-1$
282
			StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, "Context UI initialization failed", //$NON-NLS-1$
263
					e));
283
					e));
Lines 289-297 Link Here
289
		}
309
		}
290
	}
310
	}
291
311
312
	private void migrateContextMementos(ContextMementoManager mementoManager) {
313
		ScopedPreferenceStore preferenceStore = new ScopedPreferenceStore(new InstanceScope(),
314
				"org.eclipse.mylyn.resources.ui"); //$NON-NLS-1$
315
316
		IEclipsePreferences[] nodes = preferenceStore.getPreferenceNodes(false);
317
		if (nodes.length > 0) {
318
			String[] keys;
319
			try {
320
				keys = nodes[0].keys();
321
				for (String key : keys) {
322
					if (key.startsWith(EDITOR_MEMNTO_PREFS_PREFIX)) {
323
						String contextHandle = key.substring(EDITOR_MEMNTO_PREFS_PREFIX.length());
324
						String mementoString = preferenceStore.getString(key);
325
						if (mementoString != null && !mementoString.trim().equals("")) { //$NON-NLS-1$
326
							try {
327
								IMemento oldMemento = XMLMemento.createReadRoot(new StringReader(mementoString));
328
								InteractionContext context = new InteractionContext(contextHandle,
329
										ContextCore.getCommonContextScaling());
330
								ContextMemento state = mementoManager.createMemento(context);
331
								IMemento newMemnto = state.createMemento("editors");
332
								newMemnto.putMemento(oldMemento);
333
								mementoManager.write(state);
334
							} catch (WorkbenchException e) {
335
								StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN,
336
										"Migration of editor memento failed", e)); //$NON-NLS-1$
337
							}
338
						}
339
					}
340
				}
341
			} catch (BackingStoreException e) {
342
				StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN,
343
						"Migration of editor mementos failed", e)); //$NON-NLS-1$
344
			}
345
		}
346
	}
347
292
	private void lazyStop() {
348
	private void lazyStop() {
293
		if (editorManager != null) {
349
		if (editorManager != null) {
294
			ContextCore.getContextManager().removeListener(editorManager);
350
			editorManager.stop(ContextCore.getContextManager(), mementoManager);
351
		}
352
353
		if (mementoManager != null) {
354
			mementoManager.stop();
295
		}
355
		}
296
356
297
		ContextCore.getContextManager().removeListener(viewerManager);
357
		ContextCore.getContextManager().removeListener(viewerManager);
Lines 645-648 Link Here
645
	public static ContextPerspectiveManager getPerspectiveManager() {
705
	public static ContextPerspectiveManager getPerspectiveManager() {
646
		return INSTANCE.perspectiveManager;
706
		return INSTANCE.perspectiveManager;
647
	}
707
	}
708
709
	private File getContextMementoPath() {
710
		IPath stateLocation = Platform.getStateLocation(getBundle());
711
		IPath cacheFile = stateLocation.append("workbench"); //$NON-NLS-1$
712
		return cacheFile.toFile();
713
	}
714
715
	public ContextMementoManager getMementoManager() {
716
		return mementoManager;
717
	}
718
648
}
719
}
(-)src/org/eclipse/mylyn/internal/context/ui/ContextEditorManager.java (-69 / +97 lines)
Lines 11-19 Link Here
11
11
12
package org.eclipse.mylyn.internal.context.ui;
12
package org.eclipse.mylyn.internal.context.ui;
13
13
14
import java.io.IOException;
15
import java.io.StringReader;
16
import java.io.StringWriter;
17
import java.util.ArrayList;
14
import java.util.ArrayList;
18
import java.util.Arrays;
15
import java.util.Arrays;
19
import java.util.HashSet;
16
import java.util.HashSet;
Lines 23-35 Link Here
23
import org.eclipse.core.runtime.IStatus;
20
import org.eclipse.core.runtime.IStatus;
24
import org.eclipse.core.runtime.MultiStatus;
21
import org.eclipse.core.runtime.MultiStatus;
25
import org.eclipse.core.runtime.Status;
22
import org.eclipse.core.runtime.Status;
26
import org.eclipse.core.runtime.preferences.InstanceScope;
27
import org.eclipse.jface.preference.IPreferenceStore;
28
import org.eclipse.mylyn.commons.core.StatusHandler;
23
import org.eclipse.mylyn.commons.core.StatusHandler;
29
import org.eclipse.mylyn.context.core.AbstractContextListener;
24
import org.eclipse.mylyn.context.core.AbstractContextListener;
30
import org.eclipse.mylyn.context.core.AbstractContextStructureBridge;
25
import org.eclipse.mylyn.context.core.AbstractContextStructureBridge;
31
import org.eclipse.mylyn.context.core.ContextCore;
26
import org.eclipse.mylyn.context.core.ContextCore;
32
import org.eclipse.mylyn.context.core.IInteractionContext;
27
import org.eclipse.mylyn.context.core.IInteractionContext;
28
import org.eclipse.mylyn.context.core.IInteractionContextManager;
33
import org.eclipse.mylyn.context.core.IInteractionElement;
29
import org.eclipse.mylyn.context.core.IInteractionElement;
34
import org.eclipse.mylyn.context.ui.AbstractContextUiBridge;
30
import org.eclipse.mylyn.context.ui.AbstractContextUiBridge;
35
import org.eclipse.mylyn.context.ui.ContextUi;
31
import org.eclipse.mylyn.context.ui.ContextUi;
Lines 46-70 Link Here
46
import org.eclipse.ui.IWorkbenchWindow;
42
import org.eclipse.ui.IWorkbenchWindow;
47
import org.eclipse.ui.PartInitException;
43
import org.eclipse.ui.PartInitException;
48
import org.eclipse.ui.PlatformUI;
44
import org.eclipse.ui.PlatformUI;
49
import org.eclipse.ui.XMLMemento;
50
import org.eclipse.ui.internal.EditorManager;
45
import org.eclipse.ui.internal.EditorManager;
51
import org.eclipse.ui.internal.IPreferenceConstants;
46
import org.eclipse.ui.internal.IPreferenceConstants;
52
import org.eclipse.ui.internal.IWorkbenchConstants;
47
import org.eclipse.ui.internal.IWorkbenchConstants;
53
import org.eclipse.ui.internal.Workbench;
48
import org.eclipse.ui.internal.Workbench;
54
import org.eclipse.ui.internal.WorkbenchMessages;
55
import org.eclipse.ui.internal.WorkbenchPage;
49
import org.eclipse.ui.internal.WorkbenchPage;
56
import org.eclipse.ui.internal.WorkbenchWindow;
50
import org.eclipse.ui.internal.WorkbenchWindow;
57
import org.eclipse.ui.preferences.ScopedPreferenceStore;
58
51
59
/**
52
/**
60
 * @author Mik Kersten
53
 * @author Mik Kersten
61
 * @author Shawn Minto
54
 * @author Shawn Minto
62
 */
55
 */
63
public class ContextEditorManager extends AbstractContextListener {
56
public class ContextEditorManager {
64
57
65
	private static final String PREFS_PREFIX = "editors.task."; //$NON-NLS-1$
58
	private class MementoListener extends ContextMementoListener {
66
59
67
	private static final String KEY_CONTEXT_EDITORS = "ContextOpenEditors"; //$NON-NLS-1$
60
		@Override
61
		public void clearState(ContextMemento memento) {
62
			ContextEditorManager.this.clearState(memento);
63
		}
64
65
		@Override
66
		public void restoreState(ContextMemento memento) {
67
			ContextEditorManager.this.restoreState(memento);
68
		}
69
70
		@Override
71
		public void saveState(ContextMemento memento) {
72
			ContextEditorManager.this.saveState(memento);
73
		}
74
75
	}
76
77
	private class ContextListener extends AbstractContextListener {
78
79
		@Override
80
		public void interestChanged(List<IInteractionElement> elements) {
81
			for (IInteractionElement element : elements) {
82
				closeEditor(element, false);
83
			}
84
		}
85
86
		@Override
87
		public void elementsDeleted(List<IInteractionElement> elements) {
88
			for (IInteractionElement element : elements) {
89
				closeEditor(element, true);
90
			}
91
		}
92
93
	}
68
94
69
	private static final String KEY_MONITORED_WINDOW_OPEN_EDITORS = "MonitoredWindowOpenEditors"; //$NON-NLS-1$
95
	private static final String KEY_MONITORED_WINDOW_OPEN_EDITORS = "MonitoredWindowOpenEditors"; //$NON-NLS-1$
70
96
Lines 79-92 Link Here
79
	private boolean previousCloseEditorsSetting = Workbench.getInstance().getPreferenceStore().getBoolean(
105
	private boolean previousCloseEditorsSetting = Workbench.getInstance().getPreferenceStore().getBoolean(
80
			IPreferenceConstants.REUSE_EDITORS_BOOLEAN);
106
			IPreferenceConstants.REUSE_EDITORS_BOOLEAN);
81
107
82
	private final IPreferenceStore preferenceStore;
108
	private final MementoListener mementoListener;
109
110
	private final ContextListener contextListener;
111
112
	//private final IPreferenceStore preferenceStore;
83
113
84
	public ContextEditorManager() {
114
	public ContextEditorManager() {
85
		preferenceStore = new ScopedPreferenceStore(new InstanceScope(), "org.eclipse.mylyn.resources.ui"); //$NON-NLS-1$
115
		//preferenceStore = new ScopedPreferenceStore(new InstanceScope(), "org.eclipse.mylyn.resources.ui"); //$NON-NLS-1$
116
		this.mementoListener = new MementoListener();
117
		this.contextListener = new ContextListener();
86
	}
118
	}
87
119
88
	@Override
120
	public void start(IInteractionContextManager contextManager, ContextMementoManager mementoManager) {
89
	public void contextActivated(IInteractionContext context) {
121
		contextManager.addListener(contextListener);
122
		mementoManager.addMementoListener(mementoListener);
123
	}
124
125
	public void stop(IInteractionContextManager contextManager, ContextMementoManager mementoManager) {
126
		contextManager.removeListener(contextListener);
127
		mementoManager.removeMementoListener(mementoListener);
128
	}
129
130
	public void restoreState(ContextMemento state) {
90
		if (!Workbench.getInstance().isStarting()
131
		if (!Workbench.getInstance().isStarting()
91
				&& ContextUiPlugin.getDefault().getPreferenceStore().getBoolean(
132
				&& ContextUiPlugin.getDefault().getPreferenceStore().getBoolean(
92
						IContextUiPreferenceContstants.AUTO_MANAGE_EDITORS)) {
133
						IContextUiPreferenceContstants.AUTO_MANAGE_EDITORS)) {
Lines 103-111 Link Here
103
				// TODO change where memento is stored
144
				// TODO change where memento is stored
104
				IWorkbenchWindow activeWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
145
				IWorkbenchWindow activeWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
105
				try {
146
				try {
106
					mementoString = readEditorMemento(context);
147
					//mementoString = readEditorMemento(context);
107
					if (mementoString != null && !mementoString.trim().equals("")) { //$NON-NLS-1$
148
//					if (mementoString != null && !mementoString.trim().equals("")) { //$NON-NLS-1$
108
						IMemento memento = XMLMemento.createReadRoot(new StringReader(mementoString));
149
//						IMemento memento = XMLMemento.createReadRoot(new StringReader(mementoString));
150
					IMemento memento = state.getMemento("editors");
151
					if (memento != null) {
109
						IMemento[] children = memento.getChildren(KEY_MONITORED_WINDOW_OPEN_EDITORS);
152
						IMemento[] children = memento.getChildren(KEY_MONITORED_WINDOW_OPEN_EDITORS);
110
						if (children.length > 0) {
153
						if (children.length > 0) {
111
							// This code supports restore from multiple windows
154
							// This code supports restore from multiple windows
Lines 128-134 Link Here
128
							"Could not restore all editors, memento: \"" + mementoString + "\"", e)); //$NON-NLS-1$ //$NON-NLS-2$
171
							"Could not restore all editors, memento: \"" + mementoString + "\"", e)); //$NON-NLS-1$ //$NON-NLS-2$
129
				}
172
				}
130
				activeWindow.setActivePage(activeWindow.getActivePage());
173
				activeWindow.setActivePage(activeWindow.getActivePage());
131
				IInteractionElement activeNode = context.getActiveNode();
174
				IInteractionElement activeNode = state.getContext().getActiveNode();
132
				if (activeNode != null) {
175
				if (activeNode != null) {
133
					ContextUi.getUiBridge(activeNode.getContentType()).open(activeNode);
176
					ContextUi.getUiBridge(activeNode.getContentType()).open(activeNode);
134
				}
177
				}
Lines 142-148 Link Here
142
	}
185
	}
143
186
144
	private WorkbenchPage getWorkbenchPageForMemento(IMemento memento, IWorkbenchWindow activeWindow) {
187
	private WorkbenchPage getWorkbenchPageForMemento(IMemento memento, IWorkbenchWindow activeWindow) {
145
146
		String windowToRestoreClassName = memento.getString(ATTRIBUTE_CLASS);
188
		String windowToRestoreClassName = memento.getString(ATTRIBUTE_CLASS);
147
		if (windowToRestoreClassName == null) {
189
		if (windowToRestoreClassName == null) {
148
			windowToRestoreClassName = ""; //$NON-NLS-1$
190
			windowToRestoreClassName = ""; //$NON-NLS-1$
Lines 196-218 Link Here
196
		return null;
238
		return null;
197
	}
239
	}
198
240
199
	private String readEditorMemento(IInteractionContext context) {
241
//	private String readEditorMemento(IInteractionContext context) {
200
		return preferenceStore.getString(PREFS_PREFIX + context.getHandleIdentifier());
242
//		return preferenceStore.getString(PREFS_PREFIX + context.getHandleIdentifier());
201
	}
243
//	}
202
244
203
	@Override
245
	public void saveState(ContextMemento state) {
204
	public void contextDeactivated(IInteractionContext context) {
205
		if (!PlatformUI.getWorkbench().isClosing()
246
		if (!PlatformUI.getWorkbench().isClosing()
206
				&& ContextUiPlugin.getDefault().getPreferenceStore().getBoolean(
247
				&& ContextUiPlugin.getDefault().getPreferenceStore().getBoolean(
207
						IContextUiPreferenceContstants.AUTO_MANAGE_EDITORS)) {
248
						IContextUiPreferenceContstants.AUTO_MANAGE_EDITORS)) {
208
			closeAllButActiveTaskEditor(context.getHandleIdentifier());
249
			closeAllButActiveTaskEditor(state.getContext().getHandleIdentifier());
209
250
210
			XMLMemento rootMemento = XMLMemento.createWriteRoot(KEY_CONTEXT_EDITORS);
251
			//XMLMemento rootMemento = XMLMemento.createWriteRoot(KEY_CONTEXT_EDITORS);
211
252
212
			IWorkbenchWindow activeWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
253
			IWorkbenchWindow activeWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
213
			IWorkbenchWindow launchingWindow = MonitorUi.getLaunchingWorkbenchWindow();
254
			IWorkbenchWindow launchingWindow = MonitorUi.getLaunchingWorkbenchWindow();
214
			Set<IWorkbenchWindow> monitoredWindows = MonitorUi.getMonitoredWindows();
255
			Set<IWorkbenchWindow> monitoredWindows = MonitorUi.getMonitoredWindows();
215
256
257
			IMemento rootMemento = state.createMemento("editors");
216
			for (IWorkbenchWindow window : monitoredWindows) {
258
			for (IWorkbenchWindow window : monitoredWindows) {
217
				IMemento memento = rootMemento.createChild(KEY_MONITORED_WINDOW_OPEN_EDITORS);
259
				IMemento memento = rootMemento.createChild(KEY_MONITORED_WINDOW_OPEN_EDITORS);
218
260
Lines 227-241 Link Here
227
				memento.putString(ATTRIBUTE_IS_ACTIVE, (window == activeWindow) ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
269
				memento.putString(ATTRIBUTE_IS_ACTIVE, (window == activeWindow) ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
228
				((WorkbenchPage) window.getActivePage()).getEditorManager().saveState(memento);
270
				((WorkbenchPage) window.getActivePage()).getEditorManager().saveState(memento);
229
			}
271
			}
230
			// TODO: avoid storing with preferences due to bloat?
272
//			// TODO: avoid storing with preferences due to bloat?
231
			StringWriter writer = new StringWriter();
273
//			StringWriter writer = new StringWriter();
232
			try {
274
//			try {
233
				rootMemento.save(writer);
275
//				rootMemento.save(writer);
234
				writeEditorMemento(context, writer.getBuffer().toString());
276
//				writeEditorMemento(context, writer.getBuffer().toString());
235
			} catch (IOException e) {
277
//			} catch (IOException e) {
236
				StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, "Could not store editor state", //$NON-NLS-1$
278
//				StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, "Could not store editor state", //$NON-NLS-1$
237
						e));
279
//						e));
238
			}
280
//			}
239
281
240
			Workbench.getInstance().getPreferenceStore().setValue(IPreferenceConstants.REUSE_EDITORS_BOOLEAN,
282
			Workbench.getInstance().getPreferenceStore().setValue(IPreferenceConstants.REUSE_EDITORS_BOOLEAN,
241
					previousCloseEditorsSetting);
283
					previousCloseEditorsSetting);
Lines 243-268 Link Here
243
		}
285
		}
244
	}
286
	}
245
287
246
	public void writeEditorMemento(IInteractionContext context, String memento) {
288
//	public void writeEditorMemento(IInteractionContext context, String memento) {
247
		preferenceStore.setValue(PREFS_PREFIX + context.getHandleIdentifier(), memento);
289
//		preferenceStore.setValue(PREFS_PREFIX + context.getHandleIdentifier(), memento);
248
	}
290
//	}
249
291
250
	@Override
292
	public void clearState(ContextMemento memento) {
251
	public void contextCleared(IInteractionContext context) {
293
		IInteractionContext context = memento.getContext();
252
		if (context == null) {
294
		if (context == null) {
253
			return;
295
			return;
254
		}
296
		}
255
		closeAllButActiveTaskEditor(context.getHandleIdentifier());
297
		closeAllButActiveTaskEditor(context.getHandleIdentifier());
256
		XMLMemento memento = XMLMemento.createWriteRoot(KEY_CONTEXT_EDITORS);
257
298
258
		// TODO: avoid storing with preferences due to bloat?
299
//		XMLMemento memento = XMLMemento.createWriteRoot(KEY_CONTEXT_EDITORS);
259
		StringWriter writer = new StringWriter();
300
//
260
		try {
301
//		// TODO: avoid storing with preferences due to bloat?
261
			memento.save(writer);
302
//		StringWriter writer = new StringWriter();
262
			writeEditorMemento(context, writer.getBuffer().toString());
303
//		try {
263
		} catch (IOException e) {
304
//			memento.save(writer);
264
			StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, "Could not store editor state", e)); //$NON-NLS-1$
305
//			writeEditorMemento(context, writer.getBuffer().toString());
265
		}
306
//		} catch (IOException e) {
307
//			StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, "Could not store editor state", e)); 
308
//		}
266
309
267
		Workbench.getInstance().getPreferenceStore().setValue(IPreferenceConstants.REUSE_EDITORS_BOOLEAN,
310
		Workbench.getInstance().getPreferenceStore().setValue(IPreferenceConstants.REUSE_EDITORS_BOOLEAN,
268
				previousCloseEditorsSetting);
311
				previousCloseEditorsSetting);
Lines 277-284 Link Here
277
		EditorManager editorManager = page.getEditorManager();
320
		EditorManager editorManager = page.getEditorManager();
278
		final ArrayList visibleEditors = new ArrayList(5);
321
		final ArrayList visibleEditors = new ArrayList(5);
279
		final IEditorReference activeEditor[] = new IEditorReference[1];
322
		final IEditorReference activeEditor[] = new IEditorReference[1];
280
		final MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK,
323
		final MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK, "", null); //$NON-NLS-1$
281
				"", null); //$NON-NLS-1$
282
324
283
		try {
325
		try {
284
			IMemento[] editorMementos = memento.getChildren(IWorkbenchConstants.TAG_EDITOR);
326
			IMemento[] editorMementos = memento.getChildren(IWorkbenchConstants.TAG_EDITOR);
Lines 310-316 Link Here
310
				}
352
				}
311
			}
353
			}
312
		} catch (Exception e) {
354
		} catch (Exception e) {
313
			StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, "Could not restore editors", e)); //$NON-NLS-1$
355
			StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, "Could not restore editors", e));
314
		}
356
		}
315
	}
357
	}
316
358
Lines 345-351 Link Here
345
				}
387
				}
346
			}
388
			}
347
		} catch (Throwable t) {
389
		} catch (Throwable t) {
348
			StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, "Could not auto close editor", t)); //$NON-NLS-1$
390
			StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, "Could not auto close editor", t));
349
		}
391
		}
350
	}
392
	}
351
393
Lines 368-374 Link Here
368
				}
410
				}
369
			}
411
			}
370
		} catch (Throwable t) {
412
		} catch (Throwable t) {
371
			StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, "Could not auto close editor", t)); //$NON-NLS-1$
413
			StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, "Could not auto close editor", t));
372
		}
414
		}
373
	}
415
	}
374
416
Lines 380-399 Link Here
380
		return true;
422
		return true;
381
	}
423
	}
382
424
383
	@Override
384
	public void interestChanged(List<IInteractionElement> elements) {
385
		for (IInteractionElement element : elements) {
386
			closeEditor(element, false);
387
		}
388
	}
389
390
	@Override
391
	public void elementsDeleted(List<IInteractionElement> elements) {
392
		for (IInteractionElement element : elements) {
393
			closeEditor(element, true);
394
		}
395
	}
396
397
	private void closeEditor(IInteractionElement element, boolean force) {
425
	private void closeEditor(IInteractionElement element, boolean force) {
398
		if (ContextUiPlugin.getDefault().getPreferenceStore().getBoolean(
426
		if (ContextUiPlugin.getDefault().getPreferenceStore().getBoolean(
399
				IContextUiPreferenceContstants.AUTO_MANAGE_EDITORS)) {
427
				IContextUiPreferenceContstants.AUTO_MANAGE_EDITORS)) {
(-)src/org/eclipse/mylyn/internal/context/ui/ContextMementoManager.java (+248 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2008 Tasktop Technologies and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Tasktop Technologies - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylyn.internal.context.ui;
13
14
import java.io.BufferedReader;
15
import java.io.BufferedWriter;
16
import java.io.File;
17
import java.io.FileInputStream;
18
import java.io.FileOutputStream;
19
import java.io.IOException;
20
import java.io.InputStreamReader;
21
import java.io.OutputStreamWriter;
22
import java.util.HashMap;
23
import java.util.List;
24
import java.util.Map;
25
import java.util.concurrent.CopyOnWriteArrayList;
26
27
import org.eclipse.core.runtime.Assert;
28
import org.eclipse.core.runtime.IProgressMonitor;
29
import org.eclipse.core.runtime.IStatus;
30
import org.eclipse.core.runtime.MultiStatus;
31
import org.eclipse.core.runtime.SafeRunner;
32
import org.eclipse.core.runtime.Status;
33
import org.eclipse.core.runtime.jobs.Job;
34
import org.eclipse.jface.util.SafeRunnable;
35
import org.eclipse.mylyn.commons.core.StatusHandler;
36
import org.eclipse.mylyn.context.core.AbstractContextListener;
37
import org.eclipse.mylyn.context.core.IInteractionContext;
38
import org.eclipse.mylyn.context.core.IInteractionContextManager;
39
import org.eclipse.mylyn.internal.provisional.tasks.core.TasksUtil;
40
import org.eclipse.osgi.util.NLS;
41
import org.eclipse.ui.WorkbenchException;
42
import org.eclipse.ui.XMLMemento;
43
44
/**
45
 * @author Steffen Pingel
46
 */
47
public class ContextMementoManager {
48
49
	private class ContextListener extends AbstractContextListener {
50
51
		@Override
52
		public void contextActivated(IInteractionContext context) {
53
			restoreState(context);
54
		}
55
56
		@Override
57
		public void contextDeactivated(IInteractionContext context) {
58
			saveState(context);
59
		}
60
61
		@Override
62
		public void contextCleared(IInteractionContext context) {
63
			clearState(context);
64
		}
65
66
	}
67
68
	private class FlushJob extends Job {
69
70
		public FlushJob() {
71
			super("Flush context mementos"); //$NON-NLS-1$
72
		}
73
74
		@Override
75
		protected IStatus run(IProgressMonitor monitor) {
76
			ContextMementoManager.this.flushPending();
77
			return Status.OK_STATUS;
78
		}
79
80
	}
81
82
	private static final String TAG_CONTEXT_STATE = "ContextState"; //$NON-NLS-1$
83
84
	private static final long FLUSH_DELAY = 500;
85
86
	private static final String CHARSET = "UTF-8"; //$NON-NLS-1$
87
88
	private final Map<String, ContextMemento> pending;
89
90
	private final File location;
91
92
	private FlushJob flushJob;
93
94
	private boolean scheduled;
95
96
	private final IInteractionContextManager contextManager;
97
98
	private final ContextListener contextListener;
99
100
	private final List<ContextMementoListener> listeners;
101
102
	public ContextMementoManager(IInteractionContextManager contextManager, File location) {
103
		Assert.isNotNull(contextManager);
104
		Assert.isNotNull(location);
105
		this.contextManager = contextManager;
106
		this.location = location;
107
		this.contextListener = new ContextListener();
108
		this.pending = new HashMap<String, ContextMemento>();
109
		this.listeners = new CopyOnWriteArrayList<ContextMementoListener>();
110
	}
111
112
	public void addMementoListener(ContextMementoListener listener) {
113
		if (listeners.contains(listener)) {
114
			throw new IllegalStateException("listener already added"); //$NON-NLS-1$
115
		}
116
		listeners.add(listener);
117
	}
118
119
	public void removeMementoListener(ContextMementoListener listener) {
120
		listeners.remove(listener);
121
	}
122
123
	public void clearState(IInteractionContext context) {
124
125
	}
126
127
	public void saveState(IInteractionContext context) {
128
		final ContextMemento memento = createMemento(context);
129
		for (final ContextMementoListener listener : listeners) {
130
			SafeRunner.run(new SafeRunnable() {
131
				public void run() throws Exception {
132
					listener.saveState(memento);
133
				}
134
135
				@Override
136
				public void handleException(Throwable e) {
137
					StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN,
138
							"Unexpected error processing context event", e)); //$NON-NLS-1$
139
					removeMementoListener(listener);
140
				}
141
			});
142
		}
143
		if (memento.isChanged()) {
144
			writeLater(memento);
145
		}
146
	}
147
148
	ContextMemento createMemento(IInteractionContext context) {
149
		return new ContextMemento(context, XMLMemento.createWriteRoot(TAG_CONTEXT_STATE));
150
	}
151
152
	public void restoreState(IInteractionContext context) {
153
		final ContextMemento memento = read(context);
154
		for (final ContextMementoListener listener : listeners) {
155
			SafeRunner.run(new SafeRunnable() {
156
				public void run() throws Exception {
157
					listener.restoreState(memento);
158
				}
159
160
				@Override
161
				public void handleException(Throwable e) {
162
					StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN,
163
							"Unexpected error processing context event", e)); //$NON-NLS-1$
164
					removeMementoListener(listener);
165
				}
166
			});
167
		}
168
	}
169
170
	public synchronized void start() {
171
		contextManager.addListener(contextListener);
172
	}
173
174
	public synchronized void stop() {
175
		contextManager.removeListener(contextListener);
176
	}
177
178
	public synchronized void flushPending() {
179
		MultiStatus status = new MultiStatus(ContextUiPlugin.ID_PLUGIN, 0,
180
				"Failed to save context workbench state", null); //$NON-NLS-1$
181
		for (ContextMemento memento : pending.values()) {
182
			if (memento.isChanged()) {
183
				IStatus result = write(memento);
184
				status.add(result);
185
			}
186
		}
187
		pending.clear();
188
		if (!status.isOK()) {
189
			StatusHandler.log(status);
190
		}
191
	}
192
193
	private ContextMemento read(IInteractionContext context) {
194
		File file = getFile(context);
195
		if (file.exists()) {
196
			try {
197
				BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), CHARSET));
198
				XMLMemento memento = XMLMemento.createReadRoot(reader);
199
				return new ContextMemento(context, memento);
200
			} catch (IOException e) {
201
				StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, NLS.bind(
202
						"Failed to read context memento from \"{0}\"", file.getAbsolutePath()), e)); //$NON-NLS-1$
203
			} catch (WorkbenchException e) {
204
				StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, NLS.bind(
205
						"Failed to read context memento from \"{0}\"", file.getAbsolutePath()), e)); //$NON-NLS-1$
206
			}
207
		}
208
		return createMemento(context);
209
	}
210
211
	IStatus write(ContextMemento memento) {
212
		File file = getFile(memento.getContext());
213
		if (!file.getParentFile().exists()) {
214
			file.getParentFile().mkdirs();
215
		}
216
		try {
217
			BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), CHARSET));
218
			try {
219
				(memento.getMemento()).save(writer);
220
			} finally {
221
				writer.close();
222
			}
223
		} catch (IOException e) {
224
			return new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, NLS.bind(
225
					"Failed to write context memento to \"{0}\"", file.getAbsolutePath()), e); //$NON-NLS-1$
226
		}
227
		return Status.OK_STATUS;
228
	}
229
230
	private File getFile(IInteractionContext context) {
231
		return new File(location, TasksUtil.encode(context.getHandleIdentifier()));
232
	}
233
234
	public synchronized void writeLater(ContextMemento memento) {
235
		pending.put(memento.getContext().getHandleIdentifier(), memento);
236
		schedule();
237
	}
238
239
	private synchronized void schedule() {
240
		if (!scheduled) {
241
			if (flushJob == null) {
242
				flushJob = new FlushJob();
243
			}
244
			flushJob.schedule(FLUSH_DELAY);
245
		}
246
	}
247
248
}
(-)src/org/eclipse/mylyn/internal/context/ui/ContextMemento.java (+77 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2008 Tasktop Technologies and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Tasktop Technologies - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylyn.internal.context.ui;
13
14
import org.eclipse.core.runtime.Assert;
15
import org.eclipse.mylyn.context.core.IInteractionContext;
16
import org.eclipse.ui.IMemento;
17
import org.eclipse.ui.XMLMemento;
18
19
/**
20
 * Stores workspace specific settings for a context.
21
 * 
22
 * @author Steffen Pingel
23
 */
24
public class ContextMemento {
25
26
	private boolean changed;
27
28
	private final IInteractionContext context;
29
30
	private final XMLMemento memento;
31
32
	public ContextMemento(IInteractionContext context, XMLMemento memento) {
33
		Assert.isNotNull(context);
34
		Assert.isNotNull(memento);
35
		this.context = context;
36
		this.memento = memento;
37
	}
38
39
	@Override
40
	public boolean equals(Object obj) {
41
		if (!(obj instanceof ContextMemento)) {
42
			return false;
43
		}
44
		return context.equals(((ContextMemento) obj).context);
45
	}
46
47
	public IInteractionContext getContext() {
48
		return context;
49
	}
50
51
	XMLMemento getMemento() {
52
		return memento;
53
	}
54
55
	public IMemento getMemento(String type) {
56
		return memento.getChild(type);
57
	}
58
59
	public IMemento createMemento(String type) {
60
		changed = true;
61
		return memento.createChild(type);
62
	}
63
64
	@Override
65
	public int hashCode() {
66
		return context.hashCode();
67
	}
68
69
	public boolean isChanged() {
70
		return changed;
71
	}
72
73
	public void removeMemento(String type) {
74
		memento.createChild(type);
75
	}
76
77
}
(-)src/org/eclipse/mylyn/internal/context/ui/ContextMementoListener.java (+25 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2008 Tasktop Technologies and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     Tasktop Technologies - initial API and implementation
10
 *******************************************************************************/
11
12
package org.eclipse.mylyn.internal.context.ui;
13
14
/**
15
 * @author Steffen Pingel
16
 */
17
public abstract class ContextMementoListener {
18
19
	public abstract void clearState(ContextMemento memento);
20
21
	public abstract void restoreState(ContextMemento memento);
22
23
	public abstract void saveState(ContextMemento memento);
24
25
}

Return to bug 226618