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/core/ContextUtil.java (+27 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2009 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.core;
13
14
import java.io.UnsupportedEncodingException;
15
import java.net.URLEncoder;
16
17
public class ContextUtil {
18
19
	public static String encodeHandle(String handleIdentifier) {
20
		try {
21
			return URLEncoder.encode(handleIdentifier, InteractionContextManager.CONTEXT_FILENAME_ENCODING);
22
		} catch (UnsupportedEncodingException e) {
23
			throw new IllegalArgumentException("Invalid handle: " + handleIdentifier); //$NON-NLS-1$
24
		}
25
	}
26
27
}
(-)src/org/eclipse/mylyn/internal/context/ui/ContextEditorManager.java (-87 / +83 lines)
Lines 11-39 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;
20
import java.util.List;
17
import java.util.List;
21
import java.util.Set;
18
import java.util.Set;
22
19
23
import org.eclipse.core.runtime.Assert;
24
import org.eclipse.core.runtime.ISafeRunnable;
20
import org.eclipse.core.runtime.ISafeRunnable;
25
import org.eclipse.core.runtime.IStatus;
21
import org.eclipse.core.runtime.IStatus;
26
import org.eclipse.core.runtime.MultiStatus;
22
import org.eclipse.core.runtime.MultiStatus;
27
import org.eclipse.core.runtime.Status;
23
import org.eclipse.core.runtime.Status;
28
import org.eclipse.core.runtime.preferences.InstanceScope;
29
import org.eclipse.jface.preference.IPreferenceStore;
30
import org.eclipse.jface.util.SafeRunnable;
24
import org.eclipse.jface.util.SafeRunnable;
31
import org.eclipse.mylyn.commons.core.StatusHandler;
25
import org.eclipse.mylyn.commons.core.StatusHandler;
32
import org.eclipse.mylyn.context.core.AbstractContextListener;
26
import org.eclipse.mylyn.context.core.AbstractContextListener;
33
import org.eclipse.mylyn.context.core.AbstractContextStructureBridge;
27
import org.eclipse.mylyn.context.core.AbstractContextStructureBridge;
34
import org.eclipse.mylyn.context.core.ContextChangeEvent;
28
import org.eclipse.mylyn.context.core.ContextChangeEvent;
35
import org.eclipse.mylyn.context.core.ContextCore;
29
import org.eclipse.mylyn.context.core.ContextCore;
36
import org.eclipse.mylyn.context.core.IInteractionContext;
30
import org.eclipse.mylyn.context.core.IInteractionContextManager;
37
import org.eclipse.mylyn.context.core.IInteractionElement;
31
import org.eclipse.mylyn.context.core.IInteractionElement;
38
import org.eclipse.mylyn.context.ui.AbstractContextUiBridge;
32
import org.eclipse.mylyn.context.ui.AbstractContextUiBridge;
39
import org.eclipse.mylyn.context.ui.ContextUi;
33
import org.eclipse.mylyn.context.ui.ContextUi;
Lines 51-74 Link Here
51
import org.eclipse.ui.IWorkbenchWindow;
45
import org.eclipse.ui.IWorkbenchWindow;
52
import org.eclipse.ui.PartInitException;
46
import org.eclipse.ui.PartInitException;
53
import org.eclipse.ui.PlatformUI;
47
import org.eclipse.ui.PlatformUI;
54
import org.eclipse.ui.XMLMemento;
55
import org.eclipse.ui.internal.EditorManager;
48
import org.eclipse.ui.internal.EditorManager;
56
import org.eclipse.ui.internal.IPreferenceConstants;
49
import org.eclipse.ui.internal.IPreferenceConstants;
57
import org.eclipse.ui.internal.IWorkbenchConstants;
50
import org.eclipse.ui.internal.IWorkbenchConstants;
58
import org.eclipse.ui.internal.Workbench;
51
import org.eclipse.ui.internal.Workbench;
59
import org.eclipse.ui.internal.WorkbenchPage;
52
import org.eclipse.ui.internal.WorkbenchPage;
60
import org.eclipse.ui.internal.WorkbenchWindow;
53
import org.eclipse.ui.internal.WorkbenchWindow;
61
import org.eclipse.ui.preferences.ScopedPreferenceStore;
62
54
63
/**
55
/**
64
 * @author Mik Kersten
56
 * @author Mik Kersten
65
 * @author Shawn Minto
57
 * @author Shawn Minto
66
 */
58
 */
67
public class ContextEditorManager extends AbstractContextListener {
59
public class ContextEditorManager {
68
60
69
	private static final String PREFS_PREFIX = "editors.task."; //$NON-NLS-1$
61
	static final String MEMENTO_EDITORS = "org.eclipse.mylyn.context.ui.editors"; //$NON-NLS-1$
70
62
71
	private static final String KEY_CONTEXT_EDITORS = "ContextOpenEditors"; //$NON-NLS-1$
63
	private class MementoListener extends ContextMementoListener {
64
65
		@Override
66
		public void clearState(String contextHandle, boolean isActiveContext) {
67
			ContextEditorManager.this.clearState(contextHandle, isActiveContext);
68
		}
69
70
		@Override
71
		public void restoreState(ContextMemento memento) {
72
			ContextEditorManager.this.restoreState(memento);
73
		}
74
75
		@Override
76
		public void saveState(ContextMemento memento) {
77
			ContextEditorManager.this.saveState(memento);
78
		}
79
80
	}
81
82
	private class ContextListener extends AbstractContextListener {
83
84
		@Override
85
		public void contextChanged(ContextChangeEvent event) {
86
			switch (event.getEventKind()) {
87
			case INTEREST_CHANGED:
88
				for (IInteractionElement element : event.getElements()) {
89
					closeEditor(element, false);
90
				}
91
				break;
92
			case ELEMENTS_DELETED:
93
				for (IInteractionElement element : event.getElements()) {
94
					closeEditor(element, true);
95
				}
96
				break;
97
			}
98
		}
99
	}
72
100
73
	private static final String KEY_MONITORED_WINDOW_OPEN_EDITORS = "MonitoredWindowOpenEditors"; //$NON-NLS-1$
101
	private static final String KEY_MONITORED_WINDOW_OPEN_EDITORS = "MonitoredWindowOpenEditors"; //$NON-NLS-1$
74
102
Lines 83-123 Link Here
83
	private boolean previousCloseEditorsSetting = Workbench.getInstance().getPreferenceStore().getBoolean(
111
	private boolean previousCloseEditorsSetting = Workbench.getInstance().getPreferenceStore().getBoolean(
84
			IPreferenceConstants.REUSE_EDITORS_BOOLEAN);
112
			IPreferenceConstants.REUSE_EDITORS_BOOLEAN);
85
113
86
	private final IPreferenceStore preferenceStore;
114
	private final MementoListener mementoListener;
115
116
	private final ContextListener contextListener;
117
118
	//private final IPreferenceStore preferenceStore;
87
119
88
	public ContextEditorManager() {
120
	public ContextEditorManager() {
89
		preferenceStore = new ScopedPreferenceStore(new InstanceScope(), "org.eclipse.mylyn.resources.ui"); //$NON-NLS-1$
121
		//preferenceStore = new ScopedPreferenceStore(new InstanceScope(), "org.eclipse.mylyn.resources.ui"); //$NON-NLS-1$
122
		this.mementoListener = new MementoListener();
123
		this.contextListener = new ContextListener();
90
	}
124
	}
91
125
92
	@Override
126
	public void start(IInteractionContextManager contextManager, ContextMementoManager mementoManager) {
93
	public void contextChanged(ContextChangeEvent event) {
127
		contextManager.addListener(contextListener);
94
		switch (event.getEventKind()) {
128
		mementoManager.addMementoListener(mementoListener);
95
		case ACTIVATED:
129
	}
96
			openEditorsFromMemento(event.getContext());
97
			break;
98
		case DEACTIVATED:
99
			closeEditorsAndSaveMemento(event.getContext());
100
			break;
101
		case INTEREST_CHANGED:
102
			for (IInteractionElement element : event.getElements()) {
103
				closeEditor(element, false);
104
			}
105
			break;
106
		case ELEMENTS_DELETED:
107
			for (IInteractionElement element : event.getElements()) {
108
				closeEditor(element, true);
109
			}
110
			break;
111
		case CLEARED:
112
			// use the handle since the context is null when it is cleared
113
			// bug 255588
114
			clearEditorMemento(event.getContextHandle(), event.isActiveContext());
115
			break;
116
130
117
		}
131
	public void stop(IInteractionContextManager contextManager, ContextMementoManager mementoManager) {
132
		contextManager.removeListener(contextListener);
133
		mementoManager.removeMementoListener(mementoListener);
118
	}
134
	}
119
135
120
	public void openEditorsFromMemento(IInteractionContext context) {
136
	public void restoreState(ContextMemento state) {
121
		if (!Workbench.getInstance().isStarting()
137
		if (!Workbench.getInstance().isStarting()
122
				&& ContextUiPlugin.getDefault().getPreferenceStore().getBoolean(
138
				&& ContextUiPlugin.getDefault().getPreferenceStore().getBoolean(
123
						IContextUiPreferenceContstants.AUTO_MANAGE_EDITORS) && !TaskMigrator.isActive()) {
139
						IContextUiPreferenceContstants.AUTO_MANAGE_EDITORS) && !TaskMigrator.isActive()) {
Lines 131-142 Link Here
131
					ContextCore.getContextManager().setContextCapturePaused(true);
147
					ContextCore.getContextManager().setContextCapturePaused(true);
132
				}
148
				}
133
				String mementoString = null;
149
				String mementoString = null;
134
				// TODO change where memento is stored
135
				IWorkbenchWindow activeWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
150
				IWorkbenchWindow activeWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
136
				try {
151
				try {
137
					mementoString = readEditorMemento(context.getHandleIdentifier());
152
//					mementoString = readEditorMemento(context.getHandleIdentifier());
138
					if (mementoString != null && !mementoString.trim().equals("")) { //$NON-NLS-1$
153
//					if (mementoString != null && !mementoString.trim().equals("")) { //$NON-NLS-1$
139
						IMemento memento = XMLMemento.createReadRoot(new StringReader(mementoString));
154
//						IMemento memento = XMLMemento.createReadRoot(new StringReader(mementoString));
155
					IMemento memento = state.getMemento(MEMENTO_EDITORS);
156
					if (memento != null) {
140
						IMemento[] children = memento.getChildren(KEY_MONITORED_WINDOW_OPEN_EDITORS);
157
						IMemento[] children = memento.getChildren(KEY_MONITORED_WINDOW_OPEN_EDITORS);
141
						if (children.length > 0) {
158
						if (children.length > 0) {
142
							// This code supports restore from multiple windows
159
							// This code supports restore from multiple windows
Lines 159-165 Link Here
159
							"Could not restore all editors, memento: \"" + mementoString + "\"", e)); //$NON-NLS-1$ //$NON-NLS-2$
176
							"Could not restore all editors, memento: \"" + mementoString + "\"", e)); //$NON-NLS-1$ //$NON-NLS-2$
160
				}
177
				}
161
				activeWindow.setActivePage(activeWindow.getActivePage());
178
				activeWindow.setActivePage(activeWindow.getActivePage());
162
				IInteractionElement activeNode = context.getActiveNode();
179
				IInteractionElement activeNode = state.getContext().getActiveNode();
163
				if (activeNode != null) {
180
				if (activeNode != null) {
164
					ContextUi.getUiBridge(activeNode.getContentType()).open(activeNode);
181
					ContextUi.getUiBridge(activeNode.getContentType()).open(activeNode);
165
				}
182
				}
Lines 173-179 Link Here
173
	}
190
	}
174
191
175
	private WorkbenchPage getWorkbenchPageForMemento(IMemento memento, IWorkbenchWindow activeWindow) {
192
	private WorkbenchPage getWorkbenchPageForMemento(IMemento memento, IWorkbenchWindow activeWindow) {
176
177
		String windowToRestoreClassName = memento.getString(ATTRIBUTE_CLASS);
193
		String windowToRestoreClassName = memento.getString(ATTRIBUTE_CLASS);
178
		if (windowToRestoreClassName == null) {
194
		if (windowToRestoreClassName == null) {
179
			windowToRestoreClassName = ""; //$NON-NLS-1$
195
			windowToRestoreClassName = ""; //$NON-NLS-1$
Lines 226-247 Link Here
226
		return null;
242
		return null;
227
	}
243
	}
228
244
229
	private String readEditorMemento(String handleIdentifier) {
245
//	private String readEditorMemento(String handleIdentifier) {
230
		return preferenceStore.getString(PREFS_PREFIX + handleIdentifier);
246
//		return preferenceStore.getString(PREFS_PREFIX + handleIdentifier);
231
	}
247
//	}
232
248
233
	public void closeEditorsAndSaveMemento(IInteractionContext context) {
249
	public void saveState(ContextMemento state) {
234
		if (!PlatformUI.getWorkbench().isClosing()
250
		if (!PlatformUI.getWorkbench().isClosing()
235
				&& ContextUiPlugin.getDefault().getPreferenceStore().getBoolean(
251
				&& ContextUiPlugin.getDefault().getPreferenceStore().getBoolean(
236
						IContextUiPreferenceContstants.AUTO_MANAGE_EDITORS) && !TaskMigrator.isActive()) {
252
						IContextUiPreferenceContstants.AUTO_MANAGE_EDITORS) && !TaskMigrator.isActive()) {
237
			closeAllButActiveTaskEditor(context.getHandleIdentifier());
253
			closeAllButActiveTaskEditor(state.getContextHandle());
238
254
239
			XMLMemento rootMemento = XMLMemento.createWriteRoot(KEY_CONTEXT_EDITORS);
255
//			XMLMemento rootMemento = XMLMemento.createWriteRoot(KEY_CONTEXT_EDITORS);
240
256
241
			IWorkbenchWindow activeWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
257
			IWorkbenchWindow activeWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
242
			IWorkbenchWindow launchingWindow = MonitorUi.getLaunchingWorkbenchWindow();
258
			IWorkbenchWindow launchingWindow = MonitorUi.getLaunchingWorkbenchWindow();
243
			Set<IWorkbenchWindow> monitoredWindows = MonitorUi.getMonitoredWindows();
259
			Set<IWorkbenchWindow> monitoredWindows = MonitorUi.getMonitoredWindows();
244
260
261
			IMemento rootMemento = state.createMemento(MEMENTO_EDITORS);
245
			for (IWorkbenchWindow window : monitoredWindows) {
262
			for (IWorkbenchWindow window : monitoredWindows) {
246
				IMemento memento = rootMemento.createChild(KEY_MONITORED_WINDOW_OPEN_EDITORS);
263
				IMemento memento = rootMemento.createChild(KEY_MONITORED_WINDOW_OPEN_EDITORS);
247
264
Lines 255-269 Link Here
255
				memento.putBoolean(ATTRIBUTE_IS_ACTIVE, window == activeWindow);
272
				memento.putBoolean(ATTRIBUTE_IS_ACTIVE, window == activeWindow);
256
				((WorkbenchPage) window.getActivePage()).getEditorManager().saveState(memento);
273
				((WorkbenchPage) window.getActivePage()).getEditorManager().saveState(memento);
257
			}
274
			}
258
			// TODO: avoid storing with preferences due to bloat?
275
//			// TODO: avoid storing with preferences due to bloat?
259
			StringWriter writer = new StringWriter();
276
//			StringWriter writer = new StringWriter();
260
			try {
277
//			try {
261
				rootMemento.save(writer);
278
//				rootMemento.save(writer);
262
				writeEditorMemento(context.getHandleIdentifier(), writer.getBuffer().toString());
279
//				writeEditorMemento(context, writer.getBuffer().toString());
263
			} catch (IOException e) {
280
//			} catch (IOException e) {
264
				StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, "Could not store editor state", //$NON-NLS-1$
281
//				StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, "Could not store editor state", //$NON-NLS-1$
265
						e));
282
//						e));
266
			}
283
//			}
267
284
268
			Workbench.getInstance().getPreferenceStore().setValue(IPreferenceConstants.REUSE_EDITORS_BOOLEAN,
285
			Workbench.getInstance().getPreferenceStore().setValue(IPreferenceConstants.REUSE_EDITORS_BOOLEAN,
269
					previousCloseEditorsSetting);
286
					previousCloseEditorsSetting);
Lines 271-297 Link Here
271
		}
288
		}
272
	}
289
	}
273
290
274
	public void writeEditorMemento(String contextHandle, String memento) {
291
//	public void writeEditorMemento(IInteractionContext context, String memento) {
275
		preferenceStore.setValue(PREFS_PREFIX + contextHandle, memento);
292
//		preferenceStore.setValue(PREFS_PREFIX + context.getHandleIdentifier(), memento);
276
	}
293
//	}
277
294
278
	public void clearEditorMemento(String contextHandle, boolean closeEditors) {
295
	public void clearState(String contextHandle, boolean closeEditors) {
279
296
280
		if (closeEditors) {
297
		if (closeEditors) {
281
			closeAllButActiveTaskEditor(contextHandle);
298
			closeAllButActiveTaskEditor(contextHandle);
282
		}
299
		}
283
300
284
		XMLMemento memento = XMLMemento.createWriteRoot(KEY_CONTEXT_EDITORS);
285
286
		// TODO: avoid storing with preferences due to bloat?
287
		StringWriter writer = new StringWriter();
288
		try {
289
			memento.save(writer);
290
			writeEditorMemento(contextHandle, writer.getBuffer().toString());
291
		} catch (IOException e) {
292
			StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, "Could not store editor state", e)); //$NON-NLS-1$
293
		}
294
295
		Workbench.getInstance().getPreferenceStore().setValue(IPreferenceConstants.REUSE_EDITORS_BOOLEAN,
301
		Workbench.getInstance().getPreferenceStore().setValue(IPreferenceConstants.REUSE_EDITORS_BOOLEAN,
296
				previousCloseEditorsSetting);
302
				previousCloseEditorsSetting);
297
		if (closeEditors) {
303
		if (closeEditors) {
Lines 302-311 Link Here
302
	/**
308
	/**
303
	 * HACK: will fail to restore different parts with same name
309
	 * HACK: will fail to restore different parts with same name
304
	 */
310
	 */
305
	@SuppressWarnings("unchecked")
306
	private void restoreEditors(WorkbenchPage page, IMemento memento, boolean isActiveWindow) {
311
	private void restoreEditors(WorkbenchPage page, IMemento memento, boolean isActiveWindow) {
307
		EditorManager editorManager = page.getEditorManager();
312
		EditorManager editorManager = page.getEditorManager();
308
		final ArrayList visibleEditors = new ArrayList(5);
313
		final ArrayList<?> visibleEditors = new ArrayList<Object>(5);
309
		final IEditorReference activeEditor[] = new IEditorReference[1];
314
		final IEditorReference activeEditor[] = new IEditorReference[1];
310
		final MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK, "", null); //$NON-NLS-1$
315
		final MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK, "", null); //$NON-NLS-1$
311
316
Lines 441-453 Link Here
441
		}
446
		}
442
	}
447
	}
443
448
444
	public void copyEditorMemento(String sourceHandle, String targetHandle) {
445
		Assert.isNotNull(sourceHandle);
446
		Assert.isNotNull(targetHandle);
447
		String memento = readEditorMemento(sourceHandle);
448
		if (memento != null) {
449
			writeEditorMemento(targetHandle, memento);
450
		}
451
	}
452
453
}
449
}
(-)src/org/eclipse/mylyn/internal/context/ui/ContextMemento.java (+93 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 dirty;
27
28
	private final IInteractionContext context;
29
30
	private String contextHandle;
31
32
	private final XMLMemento memento;
33
34
	public ContextMemento(IInteractionContext context, String contextHandle, XMLMemento memento) {
35
		Assert.isNotNull(memento);
36
		Assert.isNotNull(contextHandle);
37
		this.context = context;
38
		this.contextHandle = contextHandle;
39
		this.memento = memento;
40
	}
41
42
	void setContextHandle(String contextHandle) {
43
		this.contextHandle = contextHandle;
44
	}
45
46
	// XXX equals and hashcode should probably use the handle to determine equality
47
	@Override
48
	public boolean equals(Object obj) {
49
		if (!(obj instanceof ContextMemento)) {
50
			return false;
51
		}
52
		return context.equals(((ContextMemento) obj).context);
53
	}
54
55
	@Override
56
	public int hashCode() {
57
		return context.hashCode();
58
	}
59
60
	public String getContextHandle() {
61
		return contextHandle;
62
	}
63
64
	public IInteractionContext getContext() {
65
		return context;
66
	}
67
68
	XMLMemento getMemento() {
69
		return memento;
70
	}
71
72
	public IMemento getMemento(String type) {
73
		return memento.getChild(type);
74
	}
75
76
	public IMemento createMemento(String type) {
77
		dirty = true;
78
		return memento.createChild(type);
79
	}
80
81
	public boolean isDirty() {
82
		return dirty;
83
	}
84
85
	public void removeMemento(String type) {
86
		memento.createChild(type);
87
	}
88
89
	public void setDirty(boolean dirty) {
90
		this.dirty = dirty;
91
	}
92
93
}
(-)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(String contextHandle, boolean isActiveContext);
20
21
	public abstract void restoreState(ContextMemento memento);
22
23
	public abstract void saveState(ContextMemento memento);
24
25
}
(-)src/org/eclipse/mylyn/internal/context/ui/ContextMementoManager.java (+318 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.ContextChangeEvent;
38
import org.eclipse.mylyn.context.core.IInteractionContext;
39
import org.eclipse.mylyn.context.core.IInteractionContextManager;
40
import org.eclipse.mylyn.internal.context.core.ContextUtil;
41
import org.eclipse.osgi.util.NLS;
42
import org.eclipse.ui.WorkbenchException;
43
import org.eclipse.ui.XMLMemento;
44
45
/**
46
 * @author Steffen Pingel
47
 */
48
public class ContextMementoManager {
49
50
	private class ContextListener extends AbstractContextListener {
51
		@Override
52
		public void contextChanged(ContextChangeEvent event) {
53
			switch (event.getEventKind()) {
54
			case ACTIVATED:
55
				restoreState(event.getContext());
56
				break;
57
			case DEACTIVATED:
58
				saveState(event.getContext());
59
				break;
60
			case CLEARED:
61
				// use the handle since the context is null when it is cleared
62
				// bug 255588
63
				clearState(event.getContextHandle(), event.isActiveContext());
64
				break;
65
			}
66
		}
67
	}
68
69
	/**
70
	 * Delays writing of mementos to avoid blocking UI thread.
71
	 */
72
	private class FlushJob extends Job {
73
74
		public FlushJob() {
75
			super("Flush context mementos"); //$NON-NLS-1$
76
			setSystem(true);
77
			setPriority(Job.SHORT);
78
		}
79
80
		@Override
81
		protected IStatus run(IProgressMonitor monitor) {
82
			ContextMementoManager.this.flushPending();
83
			return Status.OK_STATUS;
84
		}
85
86
	}
87
88
	private static final String TAG_CONTEXT_STATE = "ContextState"; //$NON-NLS-1$
89
90
	private static final long FLUSH_DELAY = 500;
91
92
	private static final String CHARSET = "UTF-8"; //$NON-NLS-1$
93
94
	private static final String EXTENSION = ".xml"; //$NON-NLS-1$
95
96
	private final Map<String, ContextMemento> pending;
97
98
	private final File location;
99
100
	private FlushJob flushJob;
101
102
	private boolean scheduled;
103
104
	private final IInteractionContextManager contextManager;
105
106
	private final ContextListener contextListener;
107
108
	private final List<ContextMementoListener> listeners;
109
110
	public ContextMementoManager(IInteractionContextManager contextManager, File location) {
111
		Assert.isNotNull(contextManager);
112
		Assert.isNotNull(location);
113
		this.contextManager = contextManager;
114
		this.location = location;
115
		this.contextListener = new ContextListener();
116
		this.pending = new HashMap<String, ContextMemento>();
117
		this.listeners = new CopyOnWriteArrayList<ContextMementoListener>();
118
	}
119
120
	public void addMementoListener(ContextMementoListener listener) {
121
		if (listeners.contains(listener)) {
122
			throw new IllegalStateException("listener already added"); //$NON-NLS-1$
123
		}
124
		listeners.add(listener);
125
	}
126
127
	public void removeMementoListener(ContextMementoListener listener) {
128
		listeners.remove(listener);
129
	}
130
131
	public void clearState(final String contextHandle, final boolean isActiveContext) {
132
		final ContextMemento memento = createMemento(null, contextHandle);
133
		for (final ContextMementoListener listener : listeners) {
134
			SafeRunner.run(new SafeRunnable() {
135
				public void run() throws Exception {
136
					listener.clearState(contextHandle, isActiveContext);
137
				}
138
139
				@Override
140
				public void handleException(Throwable e) {
141
					StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN,
142
							"Unexpected error processing context event", e)); //$NON-NLS-1$
143
					removeMementoListener(listener);
144
				}
145
			});
146
		}
147
		delete(memento);
148
	}
149
150
	public void saveState(IInteractionContext context) {
151
		final ContextMemento memento = createMemento(context, context.getHandleIdentifier());
152
		for (final ContextMementoListener listener : listeners) {
153
			SafeRunner.run(new SafeRunnable() {
154
				public void run() throws Exception {
155
					listener.saveState(memento);
156
				}
157
158
				@Override
159
				public void handleException(Throwable e) {
160
					StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN,
161
							"Unexpected error processing context event", e)); //$NON-NLS-1$
162
					removeMementoListener(listener);
163
				}
164
			});
165
		}
166
		if (memento.isDirty()) {
167
			writeLater(memento);
168
		}
169
	}
170
171
	ContextMemento createMemento(IInteractionContext context, String contextHandle) {
172
		return new ContextMemento(context, contextHandle, XMLMemento.createWriteRoot(TAG_CONTEXT_STATE));
173
	}
174
175
	public void restoreState(IInteractionContext context) {
176
		final ContextMemento memento = read(context);
177
		for (final ContextMementoListener listener : listeners) {
178
			SafeRunner.run(new SafeRunnable() {
179
				public void run() throws Exception {
180
					listener.restoreState(memento);
181
				}
182
183
				@Override
184
				public void handleException(Throwable e) {
185
					StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN,
186
							"Unexpected error processing context event", e)); //$NON-NLS-1$
187
					removeMementoListener(listener);
188
				}
189
			});
190
		}
191
	}
192
193
	public synchronized void start() {
194
		contextManager.addListener(contextListener);
195
	}
196
197
	public synchronized void stop() {
198
		contextManager.removeListener(contextListener);
199
		synchronized (this) {
200
			if (flushJob != null) {
201
				flushJob.cancel();
202
				flushJob = null;
203
			}
204
		}
205
		flushPending();
206
	}
207
208
	public synchronized void flushPending() {
209
		MultiStatus status = new MultiStatus(ContextUiPlugin.ID_PLUGIN, 0,
210
				"Failed to save context workbench state", null); //$NON-NLS-1$
211
		for (ContextMemento memento : pending.values()) {
212
			if (memento.isDirty()) {
213
				IStatus result = write(memento);
214
				status.add(result);
215
			}
216
		}
217
		pending.clear();
218
		if (!status.isOK()) {
219
			StatusHandler.log(status);
220
		}
221
	}
222
223
	/**
224
	 * Public for testing.
225
	 */
226
	public ContextMemento read(IInteractionContext context) {
227
		ContextMemento memento = read(context.getHandleIdentifier(), context);
228
		if (memento == null) {
229
			memento = createMemento(context, context.getHandleIdentifier());
230
		}
231
		return memento;
232
	}
233
234
	private ContextMemento read(String contextHandle, IInteractionContext context) {
235
		synchronized (this) {
236
			ContextMemento memento = pending.get(contextHandle);
237
			if (memento != null) {
238
				return memento;
239
			}
240
		}
241
242
		File file = getFile(contextHandle);
243
		if (file.exists()) {
244
			try {
245
				BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), CHARSET));
246
				XMLMemento memento = XMLMemento.createReadRoot(reader);
247
				return new ContextMemento(context, contextHandle, memento);
248
			} catch (IOException e) {
249
				StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, NLS.bind(
250
						"Failed to read context memento from \"{0}\"", file.getAbsolutePath()), e)); //$NON-NLS-1$
251
			} catch (WorkbenchException e) {
252
				StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, NLS.bind(
253
						"Failed to read context memento from \"{0}\"", file.getAbsolutePath()), e)); //$NON-NLS-1$
254
			}
255
		}
256
		return null;
257
	}
258
259
	IStatus write(ContextMemento memento) {
260
		File file = getFile(memento.getContextHandle());
261
		if (!file.getParentFile().exists()) {
262
			file.getParentFile().mkdirs();
263
		}
264
		try {
265
			BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), CHARSET));
266
			try {
267
				memento.getMemento().save(writer);
268
			} finally {
269
				writer.close();
270
			}
271
		} catch (IOException e) {
272
			return new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, NLS.bind(
273
					"Failed to write context memento to \"{0}\"", file.getAbsolutePath()), e); //$NON-NLS-1$
274
		}
275
		return Status.OK_STATUS;
276
	}
277
278
	private File getFile(String contextHandle) {
279
		return new File(location, ContextUtil.encodeHandle(contextHandle) + EXTENSION);
280
	}
281
282
	public synchronized void delete(ContextMemento memento) {
283
		String contextHandle = memento.getContextHandle();
284
		pending.remove(contextHandle);
285
		File file = getFile(contextHandle);
286
		if (file != null && file.exists()) {
287
			boolean succeeded = file.delete();
288
			if (!succeeded) {
289
				StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, NLS.bind(
290
						"Unable to remove the editor memento \"{0}\"", file.getAbsolutePath()))); //$NON-NLS-1$
291
			}
292
		}
293
	}
294
295
	public synchronized void writeLater(ContextMemento memento) {
296
		pending.put(memento.getContextHandle(), memento);
297
		schedule();
298
	}
299
300
	private synchronized void schedule() {
301
		if (!scheduled) {
302
			if (flushJob == null) {
303
				flushJob = new FlushJob();
304
			}
305
			flushJob.schedule(FLUSH_DELAY);
306
		}
307
	}
308
309
	public void copy(String sourceHandle, String targetHandle) {
310
		Assert.isNotNull(sourceHandle);
311
		Assert.isNotNull(targetHandle);
312
		ContextMemento memento = read(sourceHandle, null);
313
		if (memento != null) {
314
			memento.setContextHandle(targetHandle);
315
			write(memento);
316
		}
317
	}
318
}
(-)src/org/eclipse/mylyn/internal/context/ui/ContextPerspectiveManager.java (-71 / +80 lines)
Lines 15-22 Link Here
15
import java.util.Set;
15
import java.util.Set;
16
16
17
import org.eclipse.jface.preference.IPreferenceStore;
17
import org.eclipse.jface.preference.IPreferenceStore;
18
import org.eclipse.mylyn.tasks.core.ITask;
18
import org.eclipse.ui.IMemento;
19
import org.eclipse.mylyn.tasks.core.ITaskActivationListener;
20
import org.eclipse.ui.IPerspectiveDescriptor;
19
import org.eclipse.ui.IPerspectiveDescriptor;
21
import org.eclipse.ui.IPerspectiveListener4;
20
import org.eclipse.ui.IPerspectiveListener4;
22
import org.eclipse.ui.IWorkbenchPage;
21
import org.eclipse.ui.IWorkbenchPage;
Lines 28-37 Link Here
28
import org.eclipse.ui.internal.registry.IActionSetDescriptor;
27
import org.eclipse.ui.internal.registry.IActionSetDescriptor;
29
28
30
/**
29
/**
30
 * Saves the active perspective on context deactivation and restores it on activation.
31
 * 
31
 * @author Mik Kersten
32
 * @author Mik Kersten
32
 * @author Shawn Minto
33
 * @author Shawn Minto
34
 * @author Steffen Pingel
33
 */
35
 */
34
public class ContextPerspectiveManager implements ITaskActivationListener, IPerspectiveListener4 {
36
public class ContextPerspectiveManager implements IPerspectiveListener4 {
37
38
	static final String KEY_ACTIVE_ID = "activeId"; //$NON-NLS-1$
39
40
	static final String MEMENTO_PERSPECTIVE = "org.eclipse.mylyn.context.ui.perspectives"; //$NON-NLS-1$
41
42
	private class MementoListener extends ContextMementoListener {
43
44
		@Override
45
		public void clearState(String contextHandle, boolean isActiveContext) {
46
			// ignore
47
		}
48
49
		@Override
50
		public void restoreState(ContextMemento memento) {
51
			ContextPerspectiveManager.this.restoreState(memento);
52
		}
53
54
		@Override
55
		public void saveState(ContextMemento memento) {
56
			ContextPerspectiveManager.this.saveState(memento);
57
		}
58
59
	}
35
60
36
	private final Set<String> managedPerspectiveIds;
61
	private final Set<String> managedPerspectiveIds;
37
62
Lines 39-46 Link Here
39
64
40
	private final IPreferenceStore preferenceStore;
65
	private final IPreferenceStore preferenceStore;
41
66
67
	private final MementoListener mementoListener;
68
42
	public ContextPerspectiveManager(IPreferenceStore preferenceStore) {
69
	public ContextPerspectiveManager(IPreferenceStore preferenceStore) {
43
		this.preferenceStore = preferenceStore;
70
		this.preferenceStore = preferenceStore;
71
		this.mementoListener = new MementoListener();
44
		this.managedPerspectiveIds = new HashSet<String>();
72
		this.managedPerspectiveIds = new HashSet<String>();
45
		this.actionSetsToSuppress = new HashSet<String>();
73
		this.actionSetsToSuppress = new HashSet<String>();
46
		actionSetsToSuppress.add("org.eclipse.ui.edit.text.actionSet.annotationNavigation"); //$NON-NLS-1$
74
		actionSetsToSuppress.add("org.eclipse.ui.edit.text.actionSet.annotationNavigation"); //$NON-NLS-1$
Lines 56-127 Link Here
56
		managedPerspectiveIds.remove(id);
84
		managedPerspectiveIds.remove(id);
57
	}
85
	}
58
86
59
	public void taskActivated(ITask task) {
87
	public void restoreState(ContextMemento state) {
60
		try {
88
		if (PlatformUI.isWorkbenchRunning() && isEnabled()) {
61
			IWorkbenchWindow launchingWindow = getWorkbenchWindow();
89
			IWorkbenchWindow launchingWindow = getWorkbenchWindow();
62
			if (launchingWindow != null) {
90
			if (launchingWindow != null) {
91
				// save current perspective
63
				IPerspectiveDescriptor descriptor = launchingWindow.getActivePage().getPerspective();
92
				IPerspectiveDescriptor descriptor = launchingWindow.getActivePage().getPerspective();
64
				setPerspectiveIdFor(null, descriptor.getId());
93
				setDefaultPerspective(descriptor.getId());
65
94
66
				String perspectiveId = getPerspectiveIdFor(task);
95
				// restore perspective
67
				showPerspective(perspectiveId);
96
				IMemento memento = state.getMemento(MEMENTO_PERSPECTIVE);
97
				if (memento != null) {
98
					String perspectiveId = memento.getString(KEY_ACTIVE_ID);
99
					showPerspective(perspectiveId);
100
				}
68
			}
101
			}
69
		} catch (Exception e) {
70
			// ignore, perspective may not have been saved, e.g. due to crash
71
		}
102
		}
72
	}
103
	}
73
104
74
	public void taskDeactivated(ITask task) {
105
	public void saveState(ContextMemento state) {
75
		try {
106
		if (PlatformUI.isWorkbenchRunning() && isEnabled()) {
76
			if (PlatformUI.isWorkbenchRunning()
107
			IWorkbenchWindow launchingWindow = getWorkbenchWindow();
77
					&& ContextUiPlugin.getDefault().getPreferenceStore().getBoolean(
108
			if (launchingWindow != null) {
78
							IContextUiPreferenceContstants.AUTO_MANAGE_PERSPECTIVES)) {
109
				IPerspectiveDescriptor descriptor = launchingWindow.getActivePage().getPerspective();
79
				IWorkbenchWindow launchingWindow = getWorkbenchWindow();
80
				if (launchingWindow != null) {
81
					IPerspectiveDescriptor descriptor = launchingWindow.getActivePage().getPerspective();
82
					setPerspectiveIdFor(task, descriptor.getId());
83
110
84
					String previousPerspectiveId = getPerspectiveIdFor(null);
111
				IMemento memento = state.createMemento(MEMENTO_PERSPECTIVE);
85
					showPerspective(previousPerspectiveId);
112
				memento.putString(KEY_ACTIVE_ID, descriptor.getId());
86
				}
113
114
				String previousPerspectiveId = getDefaultPerspective();
115
				showPerspective(previousPerspectiveId);
87
			}
116
			}
88
		} catch (Exception e) {
89
			// ignore, perspective may not have been saved, e.g. due to crash
90
		}
117
		}
91
	}
118
	}
92
119
120
	private boolean isEnabled() {
121
		return ContextUiPlugin.getDefault().getPreferenceStore().getBoolean(
122
				IContextUiPreferenceContstants.AUTO_MANAGE_PERSPECTIVES);
123
	}
124
93
	private void showPerspective(String perspectiveId) {
125
	private void showPerspective(String perspectiveId) {
94
		if (perspectiveId != null
126
		if (perspectiveId != null && perspectiveId.length() > 0) {
95
				&& perspectiveId.length() > 0
96
				&& ContextUiPlugin.getDefault().getPreferenceStore().getBoolean(
97
						IContextUiPreferenceContstants.AUTO_MANAGE_PERSPECTIVES)) {
98
			IWorkbenchWindow launchingWindow = getWorkbenchWindow();
127
			IWorkbenchWindow launchingWindow = getWorkbenchWindow();
99
			try {
128
			if (launchingWindow != null) {
100
				if (launchingWindow != null) {
129
				try {
101
					launchingWindow.getShell().setRedraw(false);
130
					launchingWindow.getShell().setRedraw(false);
102
					PlatformUI.getWorkbench().showPerspective(perspectiveId, launchingWindow);
131
					PlatformUI.getWorkbench().showPerspective(perspectiveId, launchingWindow);
103
				}
132
				} catch (Exception e) {
104
			} catch (Exception e) {
133
					// perspective's preserved id not found, ignore
105
				// perspective's preserved id not found, ignore
134
				} finally {
106
			} finally {
107
				if (launchingWindow != null) {
108
					launchingWindow.getShell().setRedraw(true);
135
					launchingWindow.getShell().setRedraw(true);
109
				}
136
				}
110
			}
137
			}
111
		}
138
		}
112
	}
139
	}
113
140
114
	public IWorkbenchWindow getWorkbenchWindow() {
115
		IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
116
		if (window == null) {
117
			IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows();
118
			if (windows.length > 0) {
119
				window = windows[0];
120
			}
121
		}
122
		return window;
123
	}
124
125
	public void perspectivePreDeactivate(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
141
	public void perspectivePreDeactivate(IWorkbenchPage page, IPerspectiveDescriptor perspective) {
126
		// ignore
142
		// ignore
127
	}
143
	}
Lines 173-210 Link Here
173
		// ignore
189
		// ignore
174
	}
190
	}
175
191
176
	public void preTaskActivated(ITask task) {
192
	private String getDefaultPerspective() {
177
		// ignore	
193
		return preferenceStore.getString(IContextUiPreferenceContstants.PERSPECTIVE_NO_ACTIVE_TASK);
178
	}
194
	}
179
195
180
	public void preTaskDeactivated(ITask task) {
196
	private void setDefaultPerspective(String perspectiveId) {
181
		// ignore		
197
		preferenceStore.setValue(IContextUiPreferenceContstants.PERSPECTIVE_NO_ACTIVE_TASK, perspectiveId);
182
	}
198
	}
183
199
184
	/**
200
	public void start(ContextMementoManager mementoManager) {
185
	 * @param task
201
		mementoManager.addMementoListener(mementoListener);
186
	 *            can be null to indicate no task
202
	}
187
	 */
203
188
	private String getPerspectiveIdFor(ITask task) {
204
	public void stop(ContextMementoManager mementoManager) {
189
		if (task != null) {
205
		mementoManager.removeMementoListener(mementoListener);
190
			return preferenceStore.getString(IContextUiPreferenceContstants.PREFIX_TASK_TO_PERSPECTIVE
191
					+ task.getHandleIdentifier());
192
		} else {
193
			return preferenceStore.getString(IContextUiPreferenceContstants.PERSPECTIVE_NO_ACTIVE_TASK);
194
		}
195
	}
206
	}
196
207
197
	/**
208
	public IWorkbenchWindow getWorkbenchWindow() {
198
	 * @param task
209
		IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
199
	 *            can be null to indicate no task
210
		if (window == null) {
200
	 */
211
			IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows();
201
	private void setPerspectiveIdFor(ITask task, String perspectiveId) {
212
			if (windows.length > 0) {
202
		if (task != null) {
213
				window = windows[0];
203
			preferenceStore.setValue(IContextUiPreferenceContstants.PREFIX_TASK_TO_PERSPECTIVE
214
			}
204
					+ task.getHandleIdentifier(), perspectiveId);
205
		} else {
206
			preferenceStore.setValue(IContextUiPreferenceContstants.PERSPECTIVE_NO_ACTIVE_TASK, perspectiveId);
207
		}
215
		}
216
		return window;
208
	}
217
	}
209
218
210
}
219
}
(-)src/org/eclipse/mylyn/internal/context/ui/ContextUiPlugin.java (-4 / +165 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.IOException;
16
import java.io.StringReader;
14
import java.util.ArrayList;
17
import java.util.ArrayList;
15
import java.util.Collections;
18
import java.util.Collections;
16
import java.util.HashMap;
19
import java.util.HashMap;
Lines 28-35 Link Here
28
import org.eclipse.core.runtime.IExtensionPoint;
31
import org.eclipse.core.runtime.IExtensionPoint;
29
import org.eclipse.core.runtime.IExtensionRegistry;
32
import org.eclipse.core.runtime.IExtensionRegistry;
30
import org.eclipse.core.runtime.IStatus;
33
import org.eclipse.core.runtime.IStatus;
34
import org.eclipse.core.runtime.MultiStatus;
31
import org.eclipse.core.runtime.Platform;
35
import org.eclipse.core.runtime.Platform;
32
import org.eclipse.core.runtime.Status;
36
import org.eclipse.core.runtime.Status;
37
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
38
import org.eclipse.core.runtime.preferences.InstanceScope;
33
import org.eclipse.jface.preference.IPreferenceStore;
39
import org.eclipse.jface.preference.IPreferenceStore;
34
import org.eclipse.jface.resource.ImageDescriptor;
40
import org.eclipse.jface.resource.ImageDescriptor;
35
import org.eclipse.jface.text.TextSelection;
41
import org.eclipse.jface.text.TextSelection;
Lines 46-51 Link Here
46
import org.eclipse.mylyn.context.core.IInteractionRelation;
52
import org.eclipse.mylyn.context.core.IInteractionRelation;
47
import org.eclipse.mylyn.context.ui.AbstractContextUiBridge;
53
import org.eclipse.mylyn.context.ui.AbstractContextUiBridge;
48
import org.eclipse.mylyn.context.ui.IContextUiStartup;
54
import org.eclipse.mylyn.context.ui.IContextUiStartup;
55
import org.eclipse.mylyn.internal.context.core.ContextCorePlugin;
56
import org.eclipse.mylyn.internal.context.core.InteractionContext;
49
import org.eclipse.mylyn.internal.context.ui.wizards.RetrieveLatestContextDialog;
57
import org.eclipse.mylyn.internal.context.ui.wizards.RetrieveLatestContextDialog;
50
import org.eclipse.mylyn.internal.provisional.commons.ui.WorkbenchUtil;
58
import org.eclipse.mylyn.internal.provisional.commons.ui.WorkbenchUtil;
51
import org.eclipse.mylyn.monitor.ui.MonitorUi;
59
import org.eclipse.mylyn.monitor.ui.MonitorUi;
Lines 54-70 Link Here
54
import org.eclipse.mylyn.tasks.core.TaskActivationAdapter;
62
import org.eclipse.mylyn.tasks.core.TaskActivationAdapter;
55
import org.eclipse.mylyn.tasks.ui.ITasksUiConstants;
63
import org.eclipse.mylyn.tasks.ui.ITasksUiConstants;
56
import org.eclipse.mylyn.tasks.ui.TasksUi;
64
import org.eclipse.mylyn.tasks.ui.TasksUi;
65
import org.eclipse.osgi.util.NLS;
57
import org.eclipse.swt.graphics.Image;
66
import org.eclipse.swt.graphics.Image;
58
import org.eclipse.ui.IEditorInput;
67
import org.eclipse.ui.IEditorInput;
59
import org.eclipse.ui.IEditorPart;
68
import org.eclipse.ui.IEditorPart;
69
import org.eclipse.ui.IMemento;
60
import org.eclipse.ui.IViewPart;
70
import org.eclipse.ui.IViewPart;
61
import org.eclipse.ui.IViewReference;
71
import org.eclipse.ui.IViewReference;
62
import org.eclipse.ui.IWorkbench;
72
import org.eclipse.ui.IWorkbench;
63
import org.eclipse.ui.IWorkbenchWindow;
73
import org.eclipse.ui.IWorkbenchWindow;
64
import org.eclipse.ui.PlatformUI;
74
import org.eclipse.ui.PlatformUI;
75
import org.eclipse.ui.WorkbenchException;
76
import org.eclipse.ui.XMLMemento;
65
import org.eclipse.ui.internal.WorkbenchPlugin;
77
import org.eclipse.ui.internal.WorkbenchPlugin;
66
import org.eclipse.ui.plugin.AbstractUIPlugin;
78
import org.eclipse.ui.plugin.AbstractUIPlugin;
79
import org.eclipse.ui.preferences.ScopedPreferenceStore;
67
import org.osgi.framework.BundleContext;
80
import org.osgi.framework.BundleContext;
81
import org.osgi.service.prefs.BackingStoreException;
68
82
69
/**
83
/**
70
 * Main entry point for the Context UI.
84
 * Main entry point for the Context UI.
Lines 75-80 Link Here
75
 */
89
 */
76
public class ContextUiPlugin extends AbstractUIPlugin {
90
public class ContextUiPlugin extends AbstractUIPlugin {
77
91
92
	/**
93
	 * Only intended for tests and migration.
94
	 */
95
	@Deprecated
96
	public static final String PREFIX_TASK_TO_PERSPECTIVE = "org.eclipse.mylyn.ui.perspectives.task."; //$NON-NLS-1$
97
98
	/**
99
	 * Only intended for tests and migration.
100
	 */
101
	@Deprecated
102
	public static final String EDITOR_MEMENTO_PREFS_PREFIX = "editors.task."; //$NON-NLS-1$
103
78
	public static final String ID_PLUGIN = "org.eclipse.mylyn.context.ui"; //$NON-NLS-1$
104
	public static final String ID_PLUGIN = "org.eclipse.mylyn.context.ui"; //$NON-NLS-1$
79
105
80
	private class ContextActivationListener extends AbstractContextListener {
106
	private class ContextActivationListener extends AbstractContextListener {
Lines 206-211 Link Here
206
232
207
	private ContextEditorManager editorManager;
233
	private ContextEditorManager editorManager;
208
234
235
	private ContextMementoManager mementoManager;
236
209
	public ContextUiPlugin() {
237
	public ContextUiPlugin() {
210
		INSTANCE = this;
238
		INSTANCE = this;
211
	}
239
	}
Lines 247-257 Link Here
247
			ContextCore.getContextManager().addListener(viewerManager);
275
			ContextCore.getContextManager().addListener(viewerManager);
248
			MonitorUi.addWindowPartListener(contentOutlineManager);
276
			MonitorUi.addWindowPartListener(contentOutlineManager);
249
			perspectiveManager.addManagedPerspective(ITasksUiConstants.ID_PERSPECTIVE_PLANNING);
277
			perspectiveManager.addManagedPerspective(ITasksUiConstants.ID_PERSPECTIVE_PLANNING);
250
			TasksUi.getTaskActivityManager().addActivationListener(perspectiveManager);
278
251
			MonitorUi.addWindowPerspectiveListener(perspectiveManager);
279
			MonitorUi.addWindowPerspectiveListener(perspectiveManager);
252
			TasksUi.getTaskActivityManager().addActivationListener(TASK_ACTIVATION_LISTENER);
280
			TasksUi.getTaskActivityManager().addActivationListener(TASK_ACTIVATION_LISTENER);
253
281
254
			ContextCore.getContextManager().addListener(editorManager);
282
			mementoManager = new ContextMementoManager(ContextCore.getContextManager(), getContextMementoPath());
283
			mementoManager.start();
284
285
			editorManager = new ContextEditorManager();
286
			editorManager.start(ContextCore.getContextManager(), mementoManager);
287
288
			perspectiveManager.start(mementoManager);
289
290
			IStatus status = migrateContextMementos();
291
			if (!status.isOK()) {
292
				StatusHandler.log(status);
293
			}
255
		} catch (Exception e) {
294
		} catch (Exception e) {
256
			StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, "Context UI initialization failed", //$NON-NLS-1$
295
			StatusHandler.log(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, "Context UI initialization failed", //$NON-NLS-1$
257
					e));
296
					e));
Lines 283-297 Link Here
283
		}
322
		}
284
	}
323
	}
285
324
325
	/**
326
	 * Migrates editor mementos and perspective ids from the preferences to a memento based store in the file-system.
327
	 * <p>
328
	 * <b>Public for testing.</b>
329
	 * 
330
	 * @since 3.4
331
	 */
332
	public IStatus migrateContextMementos() {
333
		MultiStatus status = new MultiStatus(ContextUiPlugin.ID_PLUGIN, 0,
334
				"Errors migrating saved editors and perspective settings", null); //$NON-NLS-1$
335
336
		ScopedPreferenceStore perspectivePreferenceStore = new ScopedPreferenceStore(new InstanceScope(),
337
				"org.eclipse.mylyn.context.ui"); //$NON-NLS-1$
338
		ScopedPreferenceStore editorPreferenceStore = new ScopedPreferenceStore(new InstanceScope(),
339
				"org.eclipse.mylyn.resources.ui"); //$NON-NLS-1$
340
341
		// migrate editor mementos first
342
		IEclipsePreferences[] perspectiveNodes = perspectivePreferenceStore.getPreferenceNodes(false);
343
		IEclipsePreferences[] editorNodes = editorPreferenceStore.getPreferenceNodes(false);
344
		if (editorNodes.length > 0) {
345
			String[] keys;
346
			try {
347
				keys = editorNodes[0].keys();
348
				for (String key : keys) {
349
					if (key.startsWith(EDITOR_MEMENTO_PREFS_PREFIX)) {
350
						String contextHandle = key.substring(EDITOR_MEMENTO_PREFS_PREFIX.length());
351
						String mementoString = editorPreferenceStore.getString(key);
352
						if (mementoString != null && !mementoString.trim().equals("")) { //$NON-NLS-1$
353
							try {
354
								IMemento oldMemento = XMLMemento.createReadRoot(new StringReader(mementoString));
355
								InteractionContext context = new InteractionContext(contextHandle,
356
										ContextCore.getCommonContextScaling());
357
								ContextMemento state = mementoManager.createMemento(context, contextHandle);
358
359
								// migrate editors
360
								IMemento newMemnto = state.createMemento(ContextEditorManager.MEMENTO_EDITORS);
361
								newMemnto.putMemento(oldMemento);
362
363
								// migrate perspective
364
								String perspectiveId = perspectivePreferenceStore.getString(PREFIX_TASK_TO_PERSPECTIVE
365
										+ contextHandle);
366
								if (perspectiveId != null) {
367
									IMemento perspectiveMemento = state.createMemento(ContextPerspectiveManager.MEMENTO_PERSPECTIVE);
368
									perspectiveMemento.putString(ContextPerspectiveManager.KEY_ACTIVE_ID, perspectiveId);
369
								}
370
371
								mementoManager.write(state);
372
							} catch (WorkbenchException e) {
373
								status.add(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, NLS.bind(
374
										"Migration of editor memento failed for {0}", contextHandle), e)); //$NON-NLS-1$
375
							}
376
						}
377
						editorNodes[0].remove(key);
378
						if (perspectiveNodes.length > 0) {
379
							perspectiveNodes[0].remove(PREFIX_TASK_TO_PERSPECTIVE + contextHandle);
380
						}
381
					}
382
				}
383
			} catch (BackingStoreException e) {
384
				status.add(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, "Reading of editor mementos failed", e)); //$NON-NLS-1$
385
			}
386
		}
387
388
		// migrate remaining perspective mementos
389
		if (perspectiveNodes.length > 0) {
390
			try {
391
				String[] keys = perspectiveNodes[0].keys();
392
				for (String key : keys) {
393
					if (key.startsWith(PREFIX_TASK_TO_PERSPECTIVE)
394
							&& !key.equals(IContextUiPreferenceContstants.PERSPECTIVE_NO_ACTIVE_TASK)) {
395
						String contextHandle = key.substring(PREFIX_TASK_TO_PERSPECTIVE.length());
396
						String perspectiveId = perspectivePreferenceStore.getString(key);
397
						if (perspectiveId != null && perspectiveId.length() > 0) {
398
							InteractionContext context = new InteractionContext(contextHandle,
399
									ContextCore.getCommonContextScaling());
400
							ContextMemento state = mementoManager.createMemento(context, contextHandle);
401
402
							// migrate perspective
403
							IMemento perspectiveMemento = state.createMemento(ContextPerspectiveManager.MEMENTO_PERSPECTIVE);
404
							perspectiveMemento.putString(ContextPerspectiveManager.KEY_ACTIVE_ID, perspectiveId);
405
406
							mementoManager.write(state);
407
						}
408
						perspectiveNodes[0].remove(key);
409
					}
410
				}
411
			} catch (BackingStoreException e) {
412
				status.add(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN,
413
						"Reading of perspective mementos failed", e)); //$NON-NLS-1$
414
			}
415
		}
416
417
		try {
418
			editorPreferenceStore.save();
419
		} catch (IOException e) {
420
			status.add(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, "Saving of preference store failed", e)); //$NON-NLS-1$
421
		}
422
		try {
423
			perspectivePreferenceStore.save();
424
		} catch (IOException e) {
425
			status.add(new Status(IStatus.ERROR, ContextUiPlugin.ID_PLUGIN, "Saving of preference store failed", e)); //$NON-NLS-1$
426
		}
427
428
		return status;
429
	}
430
286
	private void lazyStop() {
431
	private void lazyStop() {
287
		if (editorManager != null) {
432
		if (editorManager != null) {
288
			ContextCore.getContextManager().removeListener(editorManager);
433
			editorManager.stop(ContextCore.getContextManager(), mementoManager);
434
		}
435
436
		if (perspectiveManager != null) {
437
			perspectiveManager.stop(mementoManager);
438
		}
439
440
		if (mementoManager != null) {
441
			mementoManager.stop();
289
		}
442
		}
290
443
291
		ContextCore.getContextManager().removeListener(viewerManager);
444
		ContextCore.getContextManager().removeListener(viewerManager);
292
		MonitorUi.removeWindowPartListener(contentOutlineManager);
445
		MonitorUi.removeWindowPartListener(contentOutlineManager);
293
446
294
		TasksUi.getTaskActivityManager().removeActivationListener(perspectiveManager);
295
		MonitorUi.removeWindowPerspectiveListener(perspectiveManager);
447
		MonitorUi.removeWindowPerspectiveListener(perspectiveManager);
296
		TasksUi.getTaskActivityManager().removeActivationListener(TASK_ACTIVATION_LISTENER);
448
		TasksUi.getTaskActivityManager().removeActivationListener(TASK_ACTIVATION_LISTENER);
297
	}
449
	}
Lines 639-642 Link Here
639
	public static ContextPerspectiveManager getPerspectiveManager() {
791
	public static ContextPerspectiveManager getPerspectiveManager() {
640
		return INSTANCE.perspectiveManager;
792
		return INSTANCE.perspectiveManager;
641
	}
793
	}
794
795
	public File getContextMementoPath() {
796
		return new File(ContextCorePlugin.getContextStore().getContextDirectory(), "workbench"); //$NON-NLS-1$
797
	}
798
799
	public ContextMementoManager getMementoManager() {
800
		return mementoManager;
801
	}
802
642
}
803
}
(-)src/org/eclipse/mylyn/internal/context/ui/IContextUiPreferenceContstants.java (-2 lines)
Lines 30-35 Link Here
30
30
31
	public static final String PERSPECTIVE_NO_ACTIVE_TASK = "org.eclipse.mylyn.ui.perspectives.task.none"; //$NON-NLS-1$
31
	public static final String PERSPECTIVE_NO_ACTIVE_TASK = "org.eclipse.mylyn.ui.perspectives.task.none"; //$NON-NLS-1$
32
32
33
	public static final String PREFIX_TASK_TO_PERSPECTIVE = "org.eclipse.mylyn.ui.perspectives.task."; //$NON-NLS-1$
34
35
}
33
}
(-)src/org/eclipse/mylyn/internal/context/ui/commands/CopyContextHandler.java (-1 / +1 lines)
Lines 66-72 Link Here
66
					MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
66
					MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
67
							TITLE_DIALOG, Messages.CopyContextHandler_SOURCE_TASK_DOES_HAVE_A_CONTEXT);
67
							TITLE_DIALOG, Messages.CopyContextHandler_SOURCE_TASK_DOES_HAVE_A_CONTEXT);
68
				} else {
68
				} else {
69
					ContextUiPlugin.getEditorManager().copyEditorMemento(sourceTask.getHandleIdentifier(),
69
					ContextUiPlugin.getDefault().getMementoManager().copy(sourceTask.getHandleIdentifier(),
70
							targetTask.getHandleIdentifier());
70
							targetTask.getHandleIdentifier());
71
					TasksUiInternal.activateTaskThroughCommand(targetTask);
71
					TasksUiInternal.activateTaskThroughCommand(targetTask);
72
				}
72
				}
(-)src/org/eclipse/mylyn/internal/monitor/ui/ActivityContextManager.java (-2 / +3 lines)
Lines 33-38 Link Here
33
import org.eclipse.mylyn.monitor.ui.AbstractUserActivityMonitor;
33
import org.eclipse.mylyn.monitor.ui.AbstractUserActivityMonitor;
34
import org.eclipse.mylyn.monitor.ui.IActivityContextManager;
34
import org.eclipse.mylyn.monitor.ui.IActivityContextManager;
35
import org.eclipse.mylyn.monitor.ui.IUserAttentionListener;
35
import org.eclipse.mylyn.monitor.ui.IUserAttentionListener;
36
import org.eclipse.osgi.util.NLS;
36
import org.eclipse.ui.IWorkbenchPage;
37
import org.eclipse.ui.IWorkbenchPage;
37
import org.eclipse.ui.IWorkbenchWindow;
38
import org.eclipse.ui.IWorkbenchWindow;
38
import org.eclipse.ui.IWorkingSet;
39
import org.eclipse.ui.IWorkingSet;
Lines 244-251 Link Here
244
	}
245
	}
245
246
246
	private void disableFailedMonitor(AbstractUserActivityMonitor monitor, Throwable e) {
247
	private void disableFailedMonitor(AbstractUserActivityMonitor monitor, Throwable e) {
247
		StatusHandler.log(new Status(IStatus.WARNING, ContextCorePlugin.ID_PLUGIN,
248
		StatusHandler.log(new Status(IStatus.WARNING, ContextCorePlugin.ID_PLUGIN, NLS.bind(
248
				"Activity monitor ''{0}'' was disabled due to a failure")); //$NON-NLS-1$
249
				"Activity monitor ''{0}'' was disabled due to a failure", monitor.getClass().getName()), e)); //$NON-NLS-1$
249
		activityMonitors.remove(monitor);
250
		activityMonitors.remove(monitor);
250
	}
251
	}
251
252
(-)src/org/eclipse/mylyn/tasks/tests/TaskDataExportTest.java (+4 lines)
Lines 100-105 Link Here
100
		CommonTestUtil.deleteFolder(destinationDir);
100
		CommonTestUtil.deleteFolder(destinationDir);
101
		createDirectory(destinationDir.getParentFile(), destinationDir.getName());
101
		createDirectory(destinationDir.getParentFile(), destinationDir.getName());
102
102
103
		// clean up contexts and offline data
104
		CommonTestUtil.deleteFolder(new File(mylynFolder, "contexts"));
105
		CommonTestUtil.deleteFolder(new File(mylynFolder, "tasks"));
106
103
		// Create folder/file structure
107
		// Create folder/file structure
104
		createFile(mylynFolder, "tasks.xml.zip");
108
		createFile(mylynFolder, "tasks.xml.zip");
105
		createFile(mylynFolder, "tasklist.xml.zip");
109
		createFile(mylynFolder, "tasklist.xml.zip");
(-)src/org/eclipse/mylyn/tasks/tests/TaskRepositoryManagerTest.java (-1 / +1 lines)
Lines 234-240 Link Here
234
		//manager.readRepositories(TasksUiPlugin.getDefault().getRepositoriesFilePath());
234
		//manager.readRepositories(TasksUiPlugin.getDefault().getRepositoriesFilePath());
235
235
236
		if (manager.getRepositoryConnector("bugzilla") != null) {
236
		if (manager.getRepositoryConnector("bugzilla") != null) {
237
			assertTrue(manager.getAllRepositories().contains(repository2));
237
			assertTrue(manager.getAllRepositories().contains(repository1));
238
		}
238
		}
239
		if (manager.getRepositoryConnector("jira") != null) {
239
		if (manager.getRepositoryConnector("jira") != null) {
240
			assertTrue(manager.getAllRepositories().contains(repository2));
240
			assertTrue(manager.getAllRepositories().contains(repository2));
(-)src/org/eclipse/mylyn/tasks/tests/ui/ContextPerspectiveManagerTest.java (-18 / +64 lines)
Lines 11-24 Link Here
11
11
12
package org.eclipse.mylyn.tasks.tests.ui;
12
package org.eclipse.mylyn.tasks.tests.ui;
13
13
14
import java.util.Collections;
15
14
import junit.framework.TestCase;
16
import junit.framework.TestCase;
15
17
18
import org.eclipse.core.runtime.IStatus;
19
import org.eclipse.mylyn.context.core.ContextCore;
16
import org.eclipse.mylyn.context.tests.support.ContextTestUtil;
20
import org.eclipse.mylyn.context.tests.support.ContextTestUtil;
21
import org.eclipse.mylyn.internal.context.core.InteractionContext;
22
import org.eclipse.mylyn.internal.context.ui.ContextMemento;
17
import org.eclipse.mylyn.internal.context.ui.ContextUiPlugin;
23
import org.eclipse.mylyn.internal.context.ui.ContextUiPlugin;
18
import org.eclipse.mylyn.internal.context.ui.IContextUiPreferenceContstants;
24
import org.eclipse.mylyn.internal.context.ui.IContextUiPreferenceContstants;
19
import org.eclipse.mylyn.internal.tasks.core.TaskTask;
25
import org.eclipse.mylyn.internal.tasks.core.TaskTask;
26
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
27
import org.eclipse.mylyn.internal.tasks.ui.actions.DeleteAction;
20
import org.eclipse.mylyn.tasks.tests.TaskTestUtil;
28
import org.eclipse.mylyn.tasks.tests.TaskTestUtil;
21
import org.eclipse.mylyn.tasks.ui.TasksUi;
29
import org.eclipse.mylyn.tasks.ui.TasksUi;
30
import org.eclipse.ui.IMemento;
22
import org.eclipse.ui.IWorkbenchWindow;
31
import org.eclipse.ui.IWorkbenchWindow;
23
import org.eclipse.ui.PlatformUI;
32
import org.eclipse.ui.PlatformUI;
24
33
Lines 42-47 Link Here
42
				IContextUiPreferenceContstants.AUTO_MANAGE_PERSPECTIVES);
51
				IContextUiPreferenceContstants.AUTO_MANAGE_PERSPECTIVES);
43
		ContextUiPlugin.getDefault().getPreferenceStore().setValue(
52
		ContextUiPlugin.getDefault().getPreferenceStore().setValue(
44
				IContextUiPreferenceContstants.AUTO_MANAGE_PERSPECTIVES, true);
53
				IContextUiPreferenceContstants.AUTO_MANAGE_PERSPECTIVES, true);
54
55
		ContextUiPlugin.getDefault().getMementoManager().flushPending();
45
	}
56
	}
46
57
47
	@Override
58
	@Override
Lines 51-56 Link Here
51
		TaskTestUtil.resetTaskListAndRepositories();
62
		TaskTestUtil.resetTaskListAndRepositories();
52
	}
63
	}
53
64
65
	public void testHasPlanningAndResourcePerspective() throws Exception {
66
		PlatformUI.getWorkbench().showPerspective(ID_RESOURCE_PERSPECTIVE, getWorkbenchWindow());
67
		assertEquals(ID_RESOURCE_PERSPECTIVE, getActivePerspective());
68
		PlatformUI.getWorkbench().showPerspective(ID_PLANNING_PERSPECTIVE, getWorkbenchWindow());
69
		assertEquals(ID_PLANNING_PERSPECTIVE, getActivePerspective());
70
	}
71
72
	public void testHasActiveWorkbenchWindow() throws Exception {
73
		assertNotNull("No active workbench window. Following tests are likely to fail.", PlatformUI.getWorkbench()
74
				.getActiveWorkbenchWindow());
75
	}
76
54
	public void testRestorePerspective() throws Exception {
77
	public void testRestorePerspective() throws Exception {
55
		PlatformUI.getWorkbench().showPerspective(ID_RESOURCE_PERSPECTIVE, getWorkbenchWindow());
78
		PlatformUI.getWorkbench().showPerspective(ID_RESOURCE_PERSPECTIVE, getWorkbenchWindow());
56
		assertEquals(ID_RESOURCE_PERSPECTIVE, getActivePerspective());
79
		assertEquals(ID_RESOURCE_PERSPECTIVE, getActivePerspective());
Lines 71-94 Link Here
71
		assertEquals(ID_PLANNING_PERSPECTIVE, getActivePerspective());
94
		assertEquals(ID_PLANNING_PERSPECTIVE, getActivePerspective());
72
	}
95
	}
73
96
74
	// FIXME 3.4 re-enable test
97
	public void testRecreateTask() throws Exception {
75
//	public void testRecreateTask() throws Exception {
98
		PlatformUI.getWorkbench().showPerspective(ID_RESOURCE_PERSPECTIVE, getWorkbenchWindow());
76
//		PlatformUI.getWorkbench().showPerspective(ID_RESOURCE_PERSPECTIVE, MonitorUi.getLaunchingWorkbenchWindow());
99
		TaskTask task = TaskTestUtil.createMockTask("1");
77
//		TaskTask task = TaskTestUtil.createMockTask("1");
100
		TasksUiPlugin.getTaskList().addTask(task);
78
//
101
79
//		// check that deleting task switches back to original perspective
102
		// check that deleting task switches back to original perspective
80
//		TasksUi.getTaskActivityManager().activateTask(task);
103
		TasksUi.getTaskActivityManager().activateTask(task);
81
//		PlatformUI.getWorkbench().showPerspective(ID_PLANNING_PERSPECTIVE, MonitorUi.getLaunchingWorkbenchWindow());
104
		PlatformUI.getWorkbench().showPerspective(ID_PLANNING_PERSPECTIVE, getWorkbenchWindow());
82
//		TasksUiPlugin.getTaskActivityManager().deactivateActiveTask();
105
		TasksUiPlugin.getTaskActivityManager().deactivateActiveTask();
83
//		TasksUiPlugin.getTaskList().deleteTask(task);
106
		// XXX ensure that InteractionContextManager is notified, TasksUiPlugin.getTaskList().deleteTask(task) does not do that
84
//		assertEquals(ID_RESOURCE_PERSPECTIVE, getActivePerspective());
107
		DeleteAction.performDeletion(Collections.singleton(task));
85
//
108
		assertEquals(ID_RESOURCE_PERSPECTIVE, getActivePerspective());
86
//		task = TaskTestUtil.createMockTask("1");
109
87
//
110
		task = TaskTestUtil.createMockTask("1");
88
//		// check that activating new task with the same id does not switch the perspective 
111
89
//		TasksUi.getTaskActivityManager().activateTask(task);
112
		// check that activating new task with the same id does not switch the perspective 
90
//		assertEquals(ID_RESOURCE_PERSPECTIVE, getActivePerspective());
113
		TasksUi.getTaskActivityManager().activateTask(task);
91
//	}
114
		assertEquals(ID_RESOURCE_PERSPECTIVE, getActivePerspective());
115
	}
116
117
	@SuppressWarnings("deprecation")
118
	public void testMigratePreferences() throws Exception {
119
		PlatformUI.getWorkbench().showPerspective(ID_RESOURCE_PERSPECTIVE, getWorkbenchWindow());
120
121
		TaskTask task = TaskTestUtil.createMockTask("1");
122
		ContextUiPlugin.getDefault().getPreferenceStore().setValue(
123
				ContextUiPlugin.PREFIX_TASK_TO_PERSPECTIVE + task.getHandleIdentifier(), ID_PLANNING_PERSPECTIVE);
124
125
		IStatus status = ContextUiPlugin.getDefault().migrateContextMementos();
126
		assertEquals(IStatus.OK, status.getSeverity());
127
128
		InteractionContext context = new InteractionContext(task.getHandleIdentifier(),
129
				ContextCore.getCommonContextScaling());
130
		ContextMemento state = ContextUiPlugin.getDefault().getMementoManager().read(context);
131
		IMemento memento = state.getMemento("org.eclipse.mylyn.context.ui.perspectives");
132
		assertNotNull(memento);
133
		assertEquals(ID_PLANNING_PERSPECTIVE, memento.getString("activeId"));
134
135
		assertEquals("", ContextUiPlugin.getDefault().getPreferenceStore().getString(
136
				ContextUiPlugin.PREFIX_TASK_TO_PERSPECTIVE + task.getHandleIdentifier()));
137
	}
92
138
93
	private IWorkbenchWindow getWorkbenchWindow() {
139
	private IWorkbenchWindow getWorkbenchWindow() {
94
		IWorkbenchWindow window = ContextUiPlugin.getPerspectiveManager().getWorkbenchWindow();
140
		IWorkbenchWindow window = ContextUiPlugin.getPerspectiveManager().getWorkbenchWindow();
(-)src/org/eclipse/mylyn/internal/tasks/ui/RefactorRepositoryUrlOperation.java (-26 / +42 lines)
Lines 14-27 Link Here
14
import java.io.File;
14
import java.io.File;
15
import java.lang.reflect.InvocationTargetException;
15
import java.lang.reflect.InvocationTargetException;
16
import java.net.URLDecoder;
16
import java.net.URLDecoder;
17
import java.util.ArrayList;
18
import java.util.List;
17
19
18
import org.eclipse.core.runtime.Assert;
20
import org.eclipse.core.runtime.Assert;
19
import org.eclipse.core.runtime.CoreException;
21
import org.eclipse.core.runtime.CoreException;
20
import org.eclipse.core.runtime.IProgressMonitor;
22
import org.eclipse.core.runtime.IProgressMonitor;
21
import org.eclipse.core.runtime.IStatus;
23
import org.eclipse.core.runtime.IStatus;
24
import org.eclipse.core.runtime.MultiStatus;
22
import org.eclipse.core.runtime.Status;
25
import org.eclipse.core.runtime.Status;
23
import org.eclipse.mylyn.commons.core.StatusHandler;
26
import org.eclipse.mylyn.commons.core.StatusHandler;
24
import org.eclipse.mylyn.internal.context.core.ContextCorePlugin;
27
import org.eclipse.mylyn.internal.context.core.ContextCorePlugin;
28
import org.eclipse.mylyn.internal.context.core.ContextUtil;
25
import org.eclipse.mylyn.internal.context.core.InteractionContext;
29
import org.eclipse.mylyn.internal.context.core.InteractionContext;
26
import org.eclipse.mylyn.internal.context.core.InteractionContextManager;
30
import org.eclipse.mylyn.internal.context.core.InteractionContextManager;
27
import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants;
31
import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants;
Lines 29-34 Link Here
29
import org.eclipse.mylyn.internal.tasks.core.data.TaskDataManager;
33
import org.eclipse.mylyn.internal.tasks.core.data.TaskDataManager;
30
import org.eclipse.mylyn.monitor.core.InteractionEvent;
34
import org.eclipse.mylyn.monitor.core.InteractionEvent;
31
import org.eclipse.mylyn.tasks.core.ITask;
35
import org.eclipse.mylyn.tasks.core.ITask;
36
import org.eclipse.osgi.util.NLS;
32
37
33
/**
38
/**
34
 * @author Rob Elves
39
 * @author Rob Elves
Lines 51-99 Link Here
51
	@Override
56
	@Override
52
	protected void operations(IProgressMonitor monitor) throws CoreException, InvocationTargetException,
57
	protected void operations(IProgressMonitor monitor) throws CoreException, InvocationTargetException,
53
			InterruptedException {
58
			InterruptedException {
59
		List<IStatus> result = new ArrayList<IStatus>();
54
		try {
60
		try {
55
			//TasksUiPlugin.getTaskListManager().deactivateAllTasks();
56
			monitor.beginTask(Messages.RefactorRepositoryUrlOperation_Repository_URL_update, IProgressMonitor.UNKNOWN);
61
			monitor.beginTask(Messages.RefactorRepositoryUrlOperation_Repository_URL_update, IProgressMonitor.UNKNOWN);
62
63
			//TasksUiPlugin.getTaskListManager().deactivateAllTasks();
57
			refactorOfflineHandles(oldUrl, newUrl);
64
			refactorOfflineHandles(oldUrl, newUrl);
58
			getTaskList().refactorRepositoryUrl(oldUrl, newUrl);
65
			getTaskList().refactorRepositoryUrl(oldUrl, newUrl);
66
59
			refactorMetaContextHandles(oldUrl, newUrl);
67
			refactorMetaContextHandles(oldUrl, newUrl);
60
			refactorContextFileNames();
68
			File contextDir = TasksUiPlugin.getDefault().getContextStoreDir();
69
			refactorContextFileNames(contextDir, ".xml", result); //$NON-NLS-1$
70
			refactorContextFileNames(new File(contextDir, "workbench"), ".xml", result); //$NON-NLS-1$ //$NON-NLS-2$
71
61
			TasksUiPlugin.getTaskActivityMonitor().reloadActivityTime();
72
			TasksUiPlugin.getTaskActivityMonitor().reloadActivityTime();
62
		} finally {
73
		} finally {
63
			monitor.done();
74
			monitor.done();
64
		}
75
		}
76
		if (!result.isEmpty()) {
77
			StatusHandler.log(new MultiStatus(TasksUiPlugin.ID_PLUGIN, 0, result.toArray(new IStatus[0]), NLS.bind(
78
					"Problems occured while changing URL from ''{0}'' to ''{1}''", oldUrl, newUrl), null)); //$NON-NLS-1$
79
		}
65
	}
80
	}
66
81
67
	@SuppressWarnings("restriction")
82
	public void refactorContextFileNames(File dataDir, String extension, List<IStatus> result) {
68
	public void refactorContextFileNames() {
69
70
		File dataDir = new File(TasksUiPlugin.getDefault().getDataDirectory(), ITasksCoreConstants.CONTEXTS_DIRECTORY);
71
		if (dataDir.exists() && dataDir.isDirectory()) {
83
		if (dataDir.exists() && dataDir.isDirectory()) {
72
			File[] files = dataDir.listFiles();
84
			File[] files = dataDir.listFiles();
73
			if (files != null) {
85
			if (files != null) {
74
				for (File file : dataDir.listFiles()) {
86
				for (File file : dataDir.listFiles()) {
75
					int dotIndex = file.getName().lastIndexOf(".xml"); //$NON-NLS-1$
87
					refactorContextFile(file, extension, result);
76
					if (dotIndex != -1) {
88
				}
77
						String storedHandle;
89
			}
78
						try {
90
		}
79
							storedHandle = URLDecoder.decode(file.getName().substring(0, dotIndex),
91
	}
80
									InteractionContextManager.CONTEXT_FILENAME_ENCODING);
92
81
							int delimIndex = storedHandle.lastIndexOf(RepositoryTaskHandleUtil.HANDLE_DELIM);
93
	private void refactorContextFile(File file, String extension, List<IStatus> result) {
82
							if (delimIndex != -1) {
94
		int dotIndex = file.getName().lastIndexOf(extension);
83
								String storedUrl = storedHandle.substring(0, delimIndex);
95
		if (dotIndex != -1) {
84
								if (oldUrl.equals(storedUrl)) {
96
			String storedHandle;
85
									String id = RepositoryTaskHandleUtil.getTaskId(storedHandle);
97
			try {
86
									String newHandle = RepositoryTaskHandleUtil.getHandle(newUrl, id);
98
				storedHandle = URLDecoder.decode(file.getName().substring(0, dotIndex),
87
									File newFile = ContextCorePlugin.getContextStore().getFileForContext(newHandle);
99
						InteractionContextManager.CONTEXT_FILENAME_ENCODING);
88
									file.renameTo(newFile);
100
				int delimIndex = storedHandle.lastIndexOf(RepositoryTaskHandleUtil.HANDLE_DELIM);
89
								}
101
				if (delimIndex != -1) {
90
							}
102
					String storedUrl = storedHandle.substring(0, delimIndex);
91
						} catch (Exception e) {
103
					if (oldUrl.equals(storedUrl)) {
92
							StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
104
						String id = RepositoryTaskHandleUtil.getTaskId(storedHandle);
93
									"Could not move context file: " + file.getName(), e)); //$NON-NLS-1$
105
						String newHandle = RepositoryTaskHandleUtil.getHandle(newUrl, id);
94
						}
106
						File newFile = new File(file.getParentFile(), ContextUtil.encodeHandle(newHandle) + extension);
107
						file.renameTo(newFile);
95
					}
108
					}
96
				}
109
				}
110
			} catch (Exception e) {
111
				result.add(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
112
						"Could not move context file: " + file.getName(), e)); //$NON-NLS-1$
97
			}
113
			}
98
		}
114
		}
99
	}
115
	}
(-)src/org/eclipse/mylyn/internal/tasks/ui/TasksUiPlugin.java (-1 / +1 lines)
Lines 852-858 Link Here
852
		}
852
		}
853
	}
853
	}
854
854
855
	private File getContextStoreDir() {
855
	public File getContextStoreDir() {
856
		File storeFile = new File(getDataDirectory(), ITasksCoreConstants.CONTEXTS_DIRECTORY);
856
		File storeFile = new File(getDataDirectory(), ITasksCoreConstants.CONTEXTS_DIRECTORY);
857
		if (!storeFile.exists()) {
857
		if (!storeFile.exists()) {
858
			storeFile.mkdirs();
858
			storeFile.mkdirs();

Return to bug 226618