001: /*******************************************************************************
002: * Copyright (c) 2004, 2006 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.ide.actions;
011:
012: import org.eclipse.core.runtime.Platform;
013: import org.eclipse.jface.action.Action;
014: import org.eclipse.jface.action.ActionContributionItem;
015: import org.eclipse.jface.action.IAction;
016: import org.eclipse.jface.action.IContributionItem;
017: import org.eclipse.jface.action.IMenuCreator;
018: import org.eclipse.jface.action.MenuManager;
019: import org.eclipse.jface.action.Separator;
020: import org.eclipse.jface.dialogs.MessageDialog;
021: import org.eclipse.osgi.util.NLS;
022: import org.eclipse.swt.widgets.Control;
023: import org.eclipse.swt.widgets.Menu;
024: import org.eclipse.ui.IWorkbenchWindow;
025: import org.eclipse.ui.actions.ActionFactory;
026: import org.eclipse.ui.internal.ide.ChooseWorkspaceData;
027: import org.eclipse.ui.internal.ide.ChooseWorkspaceDialog;
028: import org.eclipse.ui.internal.ide.ChooseWorkspaceWithSettingsDialog;
029: import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
030:
031: /**
032: * Implements the open workspace action. Opens a dialog prompting for a
033: * directory and then restarts the IDE on that workspace.
034: *
035: * @since 3.0
036: */
037: public class OpenWorkspaceAction extends Action implements
038: ActionFactory.IWorkbenchAction {
039:
040: /**
041: * Action responsible for opening the "Other..." dialog (ie: the workspace
042: * chooser).
043: *
044: * @since 3.3
045: *
046: */
047: class OpenDialogAction extends Action {
048:
049: OpenDialogAction() {
050: super (IDEWorkbenchMessages.OpenWorkspaceAction_other);
051: setToolTipText(IDEWorkbenchMessages.OpenWorkspaceAction_toolTip);
052: }
053:
054: /*
055: * (non-Javadoc)
056: *
057: * @see org.eclipse.jface.action.Action#run()
058: */
059: public void run() {
060: OpenWorkspaceAction.this .run();
061: }
062: }
063:
064: /**
065: * Action responsible for opening a specific workspace location
066: *
067: * @since 3.3
068: */
069: class WorkspaceMRUAction extends Action {
070:
071: private ChooseWorkspaceData data;
072:
073: private String location;
074:
075: WorkspaceMRUAction(String location, ChooseWorkspaceData data) {
076: this .location = location; // preserve the location directly -
077: // setText mucks with accelerators so we
078: // can't necessarily use it safely for
079: // manipulating the location later.
080: setText(location);
081: setToolTipText(location);
082: this .data = data;
083: }
084:
085: /*
086: * (non-Javadoc)
087: *
088: * @see org.eclipse.jface.action.Action#run()
089: */
090: public void run() {
091: data.workspaceSelected(location);
092: data.writePersistedData();
093: restart(location);
094: }
095: }
096:
097: private static final String PROP_VM = "eclipse.vm"; //$NON-NLS-1$
098:
099: private static final String PROP_VMARGS = "eclipse.vmargs"; //$NON-NLS-1$
100:
101: private static final String PROP_COMMANDS = "eclipse.commands"; //$NON-NLS-1$
102:
103: private static final String PROP_EXIT_CODE = "eclipse.exitcode"; //$NON-NLS-1$
104:
105: private static final String PROP_EXIT_DATA = "eclipse.exitdata"; //$NON-NLS-1$
106:
107: private static final String CMD_DATA = "-data"; //$NON-NLS-1$
108:
109: private static final String CMD_VMARGS = "-vmargs"; //$NON-NLS-1$
110:
111: private static final String NEW_LINE = "\n"; //$NON-NLS-1$
112:
113: private IWorkbenchWindow window;
114:
115: /**
116: * Set definition for this action and text so that it will be used for File
117: * -> Open Workspace in the argument window.
118: *
119: * @param window
120: * the window in which this action should appear
121: */
122: public OpenWorkspaceAction(IWorkbenchWindow window) {
123: super (IDEWorkbenchMessages.OpenWorkspaceAction_text,
124: IAction.AS_DROP_DOWN_MENU);
125:
126: if (window == null) {
127: throw new IllegalArgumentException();
128: }
129:
130: // TODO help?
131:
132: this .window = window;
133: setToolTipText(IDEWorkbenchMessages.OpenWorkspaceAction_toolTip);
134: setActionDefinitionId("org.eclipse.ui.file.openWorkspace"); //$NON-NLS-1$
135: setMenuCreator(new IMenuCreator() {
136: private MenuManager dropDownMenuMgr;
137:
138: /**
139: * Creates the menu manager for the drop-down.
140: */
141: private void createDropDownMenuMgr() {
142: if (dropDownMenuMgr == null) {
143: dropDownMenuMgr = new MenuManager();
144: final ChooseWorkspaceData data = new ChooseWorkspaceData(
145: Platform.getInstanceLocation().getURL());
146: data.readPersistedData();
147: String current = data.getInitialDefault();
148: String[] workspaces = data.getRecentWorkspaces();
149: for (int i = 0; i < workspaces.length; i++) {
150: if (workspaces[i] != null
151: && !workspaces[i].equals(current)) {
152: dropDownMenuMgr.add(new WorkspaceMRUAction(
153: workspaces[i], data));
154: }
155: }
156: if (!dropDownMenuMgr.isEmpty())
157: dropDownMenuMgr.add(new Separator());
158: dropDownMenuMgr.add(new OpenDialogAction());
159: }
160: }
161:
162: /*
163: * (non-Javadoc)
164: *
165: * @see org.eclipse.jface.action.IMenuCreator#getMenu(org.eclipse.swt.widgets.Control)
166: */
167: public Menu getMenu(Control parent) {
168: createDropDownMenuMgr();
169: return dropDownMenuMgr.createContextMenu(parent);
170: }
171:
172: /*
173: * (non-Javadoc)
174: *
175: * @see org.eclipse.jface.action.IMenuCreator#getMenu(org.eclipse.swt.widgets.Menu)
176: */
177: public Menu getMenu(Menu parent) {
178: createDropDownMenuMgr();
179: Menu menu = new Menu(parent);
180: IContributionItem[] items = dropDownMenuMgr.getItems();
181: for (int i = 0; i < items.length; i++) {
182: IContributionItem item = items[i];
183: IContributionItem newItem = item;
184: if (item instanceof ActionContributionItem) {
185: newItem = new ActionContributionItem(
186: ((ActionContributionItem) item)
187: .getAction());
188: }
189: newItem.fill(menu, -1);
190: }
191: return menu;
192: }
193:
194: /*
195: * (non-Javadoc)
196: *
197: * @see org.eclipse.jface.action.IMenuCreator#dispose()
198: */
199: public void dispose() {
200: if (dropDownMenuMgr != null) {
201: dropDownMenuMgr.dispose();
202: dropDownMenuMgr = null;
203: }
204: }
205: });
206: }
207:
208: /*
209: * (non-Javadoc)
210: *
211: * @see org.eclipse.jface.action.Action#run()
212: */
213: public void run() {
214: String path = promptForWorkspace();
215: if (path == null) {
216: return;
217: }
218:
219: restart(path);
220: }
221:
222: /**
223: * Restart the workbench using the specified path as the workspace location.
224: *
225: * @param path
226: * the location
227: * @since 3.3
228: */
229: private void restart(String path) {
230: String command_line = buildCommandLine(path);
231: if (command_line == null) {
232: return;
233: }
234:
235: System.setProperty(PROP_EXIT_CODE, Integer.toString(24));
236: System.setProperty(PROP_EXIT_DATA, command_line);
237: window.getWorkbench().restart();
238: }
239:
240: /**
241: * Use the ChooseWorkspaceDialog to get the new workspace from the user.
242: *
243: * @return a string naming the new workspace and null if cancel was selected
244: */
245: private String promptForWorkspace() {
246: // get the current workspace as the default
247: ChooseWorkspaceData data = new ChooseWorkspaceData(Platform
248: .getInstanceLocation().getURL());
249: ChooseWorkspaceDialog dialog = new ChooseWorkspaceWithSettingsDialog(
250: window.getShell(), data, true, false);
251: dialog.prompt(true);
252:
253: // return null if the user changed their mind
254: String selection = data.getSelection();
255: if (selection == null) {
256: return null;
257: }
258:
259: // otherwise store the new selection and return the selection
260: data.writePersistedData();
261: return selection;
262: }
263:
264: /**
265: * Create and return a string with command line options for eclipse.exe that
266: * will launch a new workbench that is the same as the currently running
267: * one, but using the argument directory as its workspace.
268: *
269: * @param workspace
270: * the directory to use as the new workspace
271: * @return a string of command line options or null on error
272: */
273: private String buildCommandLine(String workspace) {
274: String property = System.getProperty(PROP_VM);
275: if (property == null) {
276: MessageDialog
277: .openError(
278: window.getShell(),
279: IDEWorkbenchMessages.OpenWorkspaceAction_errorTitle,
280: NLS
281: .bind(
282: IDEWorkbenchMessages.OpenWorkspaceAction_errorMessage,
283: PROP_VM));
284: return null;
285: }
286:
287: StringBuffer result = new StringBuffer(512);
288: result.append(property);
289: result.append(NEW_LINE);
290:
291: // append the vmargs and commands. Assume that these already end in \n
292: String vmargs = System.getProperty(PROP_VMARGS);
293: if (vmargs != null) {
294: result.append(vmargs);
295: }
296:
297: // append the rest of the args, replacing or adding -data as required
298: property = System.getProperty(PROP_COMMANDS);
299: if (property == null) {
300: result.append(CMD_DATA);
301: result.append(NEW_LINE);
302: result.append(workspace);
303: result.append(NEW_LINE);
304: } else {
305: // find the index of the arg to replace its value
306: int cmd_data_pos = property.lastIndexOf(CMD_DATA);
307: if (cmd_data_pos != -1) {
308: cmd_data_pos += CMD_DATA.length() + 1;
309: result.append(property.substring(0, cmd_data_pos));
310: result.append(workspace);
311: result.append(property.substring(property.indexOf('\n',
312: cmd_data_pos)));
313: } else {
314: result.append(CMD_DATA);
315: result.append(NEW_LINE);
316: result.append(workspace);
317: result.append(NEW_LINE);
318: result.append(property);
319: }
320: }
321:
322: // put the vmargs back at the very end (the eclipse.commands property
323: // already contains the -vm arg)
324: if (vmargs != null) {
325: result.append(CMD_VMARGS);
326: result.append(NEW_LINE);
327: result.append(vmargs);
328: }
329:
330: return result.toString();
331: }
332:
333: /*
334: * (non-Javadoc)
335: *
336: * @see org.eclipse.jface.action.Action#dispose()
337: */
338: public void dispose() {
339: window = null;
340: }
341: }
|