001: /*******************************************************************************
002: * Copyright (c) 2006, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal;
011:
012: import java.io.File;
013: import java.io.FileOutputStream;
014: import java.io.IOException;
015: import java.io.OutputStreamWriter;
016:
017: import org.eclipse.core.runtime.IAdaptable;
018: import org.eclipse.core.runtime.IPath;
019: import org.eclipse.core.runtime.IStatus;
020: import org.eclipse.core.runtime.MultiStatus;
021: import org.eclipse.core.runtime.Status;
022: import org.eclipse.jface.dialogs.ErrorDialog;
023: import org.eclipse.osgi.util.NLS;
024: import org.eclipse.ui.IMemento;
025: import org.eclipse.ui.IPersistableElement;
026: import org.eclipse.ui.IPerspectiveDescriptor;
027: import org.eclipse.ui.IViewPart;
028: import org.eclipse.ui.IViewReference;
029: import org.eclipse.ui.IWorkbench;
030: import org.eclipse.ui.IWorkbenchPage;
031: import org.eclipse.ui.IWorkbenchPreferenceConstants;
032: import org.eclipse.ui.IWorkbenchWindow;
033: import org.eclipse.ui.PlatformUI;
034: import org.eclipse.ui.XMLMemento;
035: import org.eclipse.ui.internal.intro.IIntroConstants;
036: import org.eclipse.ui.internal.preferences.WorkbenchSettingsTransfer;
037: import org.eclipse.ui.internal.presentations.PresentationFactoryUtil;
038: import org.eclipse.ui.internal.util.PrefUtil;
039: import org.eclipse.ui.internal.util.Util;
040: import org.eclipse.ui.presentations.AbstractPresentationFactory;
041: import org.eclipse.ui.presentations.IStackPresentationSite;
042:
043: /**
044: * The WorkbenchSettings handles the recording and restoring of workbench
045: * settings.
046: *
047: * @since 3.3
048: *
049: */
050: public class WorkbenchLayoutSettingsTransfer extends
051: WorkbenchSettingsTransfer {
052:
053: // private static final String WORKBENCH_LAYOUT_PATH =
054: // ".metadata/.plugins/org.eclipse.ui.workbench/workbench.xml";
055: // //$NON-NLS-1$
056:
057: /**
058: * Create a new instance of the receiver.
059: */
060: public WorkbenchLayoutSettingsTransfer() {
061: super ();
062: }
063:
064: /**
065: * Record the sharable workbench state in a document.
066: *
067: * @return {@link XMLMemento}
068: */
069: public XMLMemento recordSharableWorkbenchState() {
070: XMLMemento memento = XMLMemento
071: .createWriteRoot(IWorkbenchConstants.TAG_WORKBENCH);
072: IStatus status = saveSettings(memento);
073: if (status.getSeverity() != IStatus.OK) {
074: // don't use newWindow as parent because it has not yet been opened
075: // (bug 76724)
076: ErrorDialog.openError(null,
077: WorkbenchMessages.Workbench_problemsSaving,
078: WorkbenchMessages.Workbench_problemsSavingMsg,
079: status);
080: }
081: return memento;
082: }
083:
084: /**
085: * Save the settings to the memento.
086: *
087: * @param memento
088: * @return IStatus
089: */
090: private IStatus saveSettings(XMLMemento memento) {
091: MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID,
092: IStatus.OK, WorkbenchMessages.Workbench_problemsSaving,
093: null);
094:
095: // Save the version number.
096: memento.putString(IWorkbenchConstants.TAG_VERSION,
097: Workbench.VERSION_STRING[1]);
098:
099: // Save the workbench windows.
100: IWorkbenchWindow[] windows = PlatformUI.getWorkbench()
101: .getWorkbenchWindows();
102: for (int nX = 0; nX < windows.length; nX++) {
103: WorkbenchWindow window = (WorkbenchWindow) windows[nX];
104: IMemento childMem = memento
105: .createChild(IWorkbenchConstants.TAG_WINDOW);
106: result.merge(saveState(window, childMem));
107: }
108: return result;
109: }
110:
111: /**
112: * Save the workbench window state.
113: *
114: * @param window
115: * @param memento
116: * @return IStatus
117: */
118: private IStatus saveState(WorkbenchWindow window, IMemento memento) {
119:
120: MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID,
121: IStatus.OK,
122: WorkbenchMessages.WorkbenchWindow_problemsSavingWindow,
123: null);
124:
125: IWorkbenchPage activePage = window.getActivePage();
126: if (activePage != null
127: && activePage.findView(IIntroConstants.INTRO_VIEW_ID) != null) {
128: IMemento introMem = memento
129: .createChild(IWorkbenchConstants.TAG_INTRO);
130: boolean isStandby = getWorkbench()
131: .getIntroManager()
132: .isIntroStandby(
133: getWorkbench().getIntroManager().getIntro());
134: introMem.putString(IWorkbenchConstants.TAG_STANDBY, String
135: .valueOf(isStandby));
136: }
137:
138: // Save each page.
139: IWorkbenchPage[] pages = window.getPages();
140: for (int i = 0; i < pages.length; i++) {
141: IWorkbenchPage page = pages[i];
142:
143: // Save perspective.
144: IMemento pageMem = memento
145: .createChild(IWorkbenchConstants.TAG_PAGE);
146: pageMem.putString(IWorkbenchConstants.TAG_LABEL, page
147: .getLabel());
148: result.add(saveState((WorkbenchPage) page, pageMem));
149:
150: if (page == window.getActivePage()) {
151: pageMem
152: .putString(IWorkbenchConstants.TAG_FOCUS,
153: "true"); //$NON-NLS-1$
154: }
155:
156: // Get the input.
157: IAdaptable input = page.getInput();
158: if (input != null) {
159: IPersistableElement persistable = (IPersistableElement) Util
160: .getAdapter(input, IPersistableElement.class);
161: if (persistable == null) {
162: WorkbenchPlugin
163: .log("Unable to save page input: " //$NON-NLS-1$
164: + input
165: + ", because it does not adapt to IPersistableElement"); //$NON-NLS-1$
166:
167: } else {
168: // Save input.
169: IMemento inputMem = pageMem
170: .createChild(IWorkbenchConstants.TAG_INPUT);
171: inputMem.putString(
172: IWorkbenchConstants.TAG_FACTORY_ID,
173: persistable.getFactoryId());
174: persistable.saveState(inputMem);
175: }
176: }
177: }
178:
179: return result;
180: }
181:
182: /**
183: * Save the state of the workbench page.
184: *
185: * @param page
186: * @param pageMem
187: * @return IStatus
188: */
189: private IStatus saveState(WorkbenchPage page, IMemento memento) {
190:
191: MultiStatus result = new MultiStatus(
192: PlatformUI.PLUGIN_ID,
193: IStatus.OK,
194: NLS
195: .bind(
196: WorkbenchMessages.WorkbenchPage_unableToSavePerspective,
197: page.getLabel()), null);
198:
199: saveEditorState(memento);
200:
201: IMemento viewMem = memento
202: .createChild(IWorkbenchConstants.TAG_VIEWS);
203:
204: IViewReference[] refs = page.getViewReferences();
205:
206: for (int i = 0; i < refs.length; i++) {
207: IViewReference viewReference = refs[i];
208: String tagId = ViewFactory.getKey(viewReference);
209: if (tagId != null) {
210: IMemento childMem = viewMem
211: .createChild(IWorkbenchConstants.TAG_VIEW);
212: childMem.putString(IWorkbenchConstants.TAG_ID, tagId);
213: String name = viewReference.getPartName();
214: if (name != null) {
215: childMem.putString(
216: IWorkbenchConstants.TAG_PART_NAME, name);
217: }
218: }
219: }
220:
221: // Create persp block.
222: IMemento perspectiveMemento = memento
223: .createChild(IWorkbenchConstants.TAG_PERSPECTIVES);
224: if (page.getPerspective() != null) {
225: perspectiveMemento.putString(
226: IWorkbenchConstants.TAG_ACTIVE_PERSPECTIVE, page
227: .getPerspective().getId());
228: }
229: if (page.getActivePart() != null) {
230: if (page.getActivePart() instanceof IViewPart) {
231: IViewReference ref = (IViewReference) page
232: .getReference(page.getActivePart());
233: if (ref != null) {
234: perspectiveMemento.putString(
235: IWorkbenchConstants.TAG_ACTIVE_PART,
236: ViewFactory.getKey(ref));
237: }
238: } else {
239: perspectiveMemento.putString(
240: IWorkbenchConstants.TAG_ACTIVE_PART, page
241: .getActivePart().getSite().getId());
242: }
243: }
244:
245: // Save each perspective in opened order
246: IPerspectiveDescriptor[] perspectives = page
247: .getOpenPerspectives();
248:
249: for (int i = 0; i < perspectives.length; i++) {
250: IPerspectiveDescriptor perspectiveDescriptor = perspectives[i];
251: IMemento gChildMem = perspectiveMemento
252: .createChild(IWorkbenchConstants.TAG_PERSPECTIVE);
253: Perspective perspective = page
254: .findPerspective(perspectiveDescriptor);
255: perspective.saveState(gChildMem);
256: }
257:
258: return result;
259:
260: }
261:
262: /**
263: * Save the editor state. Set it to be the defaults.
264: *
265: * @param memento
266: */
267: private void saveEditorState(IMemento memento) {
268:
269: IMemento editorsMemento = memento
270: .createChild(IWorkbenchConstants.TAG_EDITORS);
271: IMemento editorArea = editorsMemento
272: .createChild(IWorkbenchConstants.TAG_AREA);
273: editorArea.putString(IWorkbenchConstants.TAG_ACTIVE_WORKBOOK,
274: EditorSashContainer.DEFAULT_WORKBOOK_ID);
275: IMemento info = editorArea
276: .createChild(IWorkbenchConstants.TAG_INFO);
277: info.putString(IWorkbenchConstants.TAG_PART,
278: EditorSashContainer.DEFAULT_WORKBOOK_ID);
279: IMemento folder = info
280: .createChild(IWorkbenchConstants.TAG_FOLDER);
281: folder.putInteger(IWorkbenchConstants.TAG_APPEARANCE,
282: PresentationFactoryUtil.ROLE_EDITOR);
283: folder.putInteger(IWorkbenchConstants.TAG_EXPANDED,
284: IStackPresentationSite.STATE_RESTORED);
285: IMemento presentation = folder
286: .createChild(IWorkbenchConstants.TAG_PRESENTATION);
287: presentation.putString(IWorkbenchConstants.TAG_ID,
288: getCurrentPresentationClassName());
289:
290: }
291:
292: /**
293: * Get the name of the current presentation class name.
294: *
295: * @return String
296: */
297: private String getCurrentPresentationClassName() {
298:
299: // update the current selection (used to look for changes on apply)
300: String currentPresentationFactoryId = PrefUtil
301: .getAPIPreferenceStore()
302: .getString(
303: IWorkbenchPreferenceConstants.PRESENTATION_FACTORY_ID);
304: // Workbench.getInstance().getPresentationId();
305:
306: AbstractPresentationFactory factory = WorkbenchPlugin
307: .getDefault().getPresentationFactory(
308: currentPresentationFactoryId);
309:
310: if (factory == null)
311: factory = WorkbenchPlugin
312: .getDefault()
313: .getPresentationFactory(
314: IWorkbenchConstants.DEFAULT_PRESENTATION_ID);
315: return factory.getClass().getName();
316:
317: }
318:
319: /**
320: * Return the workbench we are using.
321: *
322: * @return IWorkbench
323: */
324: private IWorkbench getWorkbench() {
325: return PlatformUI.getWorkbench();
326: }
327:
328: /*
329: * (non-Javadoc)
330: *
331: * @see org.eclipse.ui.preferences.SettingsTransfer#transferSettings(org.eclipse.core.runtime.IPath)
332: */
333: public IStatus transferSettings(IPath newWorkspaceRoot) {
334: try {
335: File workspaceFile = createFileAndDirectories(newWorkspaceRoot);
336:
337: if (workspaceFile == null)
338: return new Status(
339: IStatus.ERROR,
340: WorkbenchPlugin.PI_WORKBENCH,
341: WorkbenchMessages.WorkbenchSettings_CouldNotCreateDirectories);
342:
343: FileOutputStream stream = new FileOutputStream(
344: workspaceFile);
345: OutputStreamWriter writer = new OutputStreamWriter(stream,
346: "utf-8"); //$NON-NLS-1$
347: XMLMemento memento = XMLMemento
348: .createWriteRoot(IWorkbenchConstants.TAG_WORKBENCH);
349: IStatus status = saveSettings(memento);
350: if (status.getSeverity() != IStatus.OK)
351: return status;
352:
353: memento.save(writer);
354: writer.close();
355:
356: } catch (IOException e) {
357: return new Status(IStatus.ERROR,
358: WorkbenchPlugin.PI_WORKBENCH,
359: WorkbenchMessages.Workbench_problemsSavingMsg, e);
360:
361: }
362:
363: return Status.OK_STATUS;
364: }
365:
366: /**
367: * Create the parent directories for the workbench layout file and then
368: * return the File.
369: *
370: * @param newWorkspaceRoot
371: * @return File the new layout file. Return <code>null</code> if the file
372: * cannot be created.
373: */
374: private File createFileAndDirectories(IPath newWorkspaceRoot) {
375: IPath newWorkspaceLocation = getNewWorkbenchStateLocation(
376: newWorkspaceRoot).append(
377: Workbench.DEFAULT_WORKBENCH_STATE_FILENAME);
378: File workspaceFile = new File(newWorkspaceLocation.toOSString());
379:
380: File parent = workspaceFile.getParentFile();
381: if (!parent.exists()) {
382: if (!parent.mkdirs())
383: return null;
384: }
385:
386: return workspaceFile;
387: }
388:
389: /*
390: * (non-Javadoc)
391: *
392: * @see org.eclipse.ui.preferences.SettingsTransfer#getName()
393: */
394: public String getName() {
395: return WorkbenchMessages.WorkbenchLayoutSettings_Name;
396: }
397:
398: }
|