| /******************************************************************************* |
| * Copyright (c) 2000, 2009 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Mohamed Tarief , IBM - Bug 139211 |
| *******************************************************************************/ |
| package org.eclipse.ui.actions; |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IResourceChangeEvent; |
| import org.eclipse.core.resources.IResourceChangeListener; |
| import org.eclipse.core.resources.IResourceDelta; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.resources.WorkspaceJob; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.OperationCanceledException; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.SubProgressMonitor; |
| import org.eclipse.core.runtime.jobs.Job; |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.jface.dialogs.MessageDialogWithToggle; |
| import org.eclipse.jface.preference.IPreferenceStore; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.window.IShellProvider; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.internal.ide.IDEInternalPreferences; |
| import org.eclipse.ui.internal.ide.IDEWorkbenchMessages; |
| import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; |
| import org.eclipse.ui.internal.ide.IIDEHelpContextIds; |
| |
| /** |
| * Standard action for opening the currently selected project(s). |
| * <p> |
| * Note that there is a different action for opening an editor on file |
| * resources: <code>OpenFileAction</code>. |
| * </p> |
| * <p> |
| * This class may be instantiated; it is not intended to be subclassed. |
| * </p> |
| * @noextend This class is not intended to be subclassed by clients. |
| */ |
| public class OpenResourceAction extends WorkspaceAction implements IResourceChangeListener { |
| |
| /** |
| * The id of this action. |
| */ |
| public static final String ID = PlatformUI.PLUGIN_ID + ".OpenResourceAction"; //$NON-NLS-1$ |
| |
| /** |
| * Creates a new action. |
| * |
| * @param shell |
| * the shell for any dialogs |
| * |
| * @deprecated {@link #OpenResourceAction(IShellProvider)} |
| */ |
| public OpenResourceAction(Shell shell) { |
| super(shell, IDEWorkbenchMessages.OpenResourceAction_text); |
| initAction(); |
| } |
| |
| /** |
| * Creates a new action. |
| * |
| * @param provider |
| * the shell for any dialogs |
| * @since 3.4 |
| */ |
| public OpenResourceAction(IShellProvider provider) { |
| super(provider, IDEWorkbenchMessages.OpenResourceAction_text); |
| initAction(); |
| } |
| |
| /** |
| * Initializes the workbench |
| */ |
| private void initAction() { |
| PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IIDEHelpContextIds.OPEN_RESOURCE_ACTION); |
| setToolTipText(IDEWorkbenchMessages.OpenResourceAction_toolTip); |
| setId(ID); |
| } |
| |
| /** |
| * Returns the total number of closed projects in the workspace. |
| */ |
| private int countClosedProjects() { |
| int count = 0; |
| IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); |
| for (int i = 0; i < projects.length; i++) { |
| if (!projects[i].isOpen()) { |
| count++; |
| } |
| } |
| return count; |
| } |
| |
| /* |
| * (non-Javadoc) Method declared on WorkspaceAction. |
| */ |
| protected String getOperationMessage() { |
| return IDEWorkbenchMessages.OpenResourceAction_operationMessage; |
| } |
| |
| /* |
| * (non-Javadoc) Method declared on WorkspaceAction. |
| */ |
| protected String getProblemsMessage() { |
| return IDEWorkbenchMessages.OpenResourceAction_problemMessage; |
| } |
| |
| /* |
| * (non-Javadoc) Method declared on WorkspaceAction. |
| */ |
| protected String getProblemsTitle() { |
| return IDEWorkbenchMessages.OpenResourceAction_dialogTitle; |
| } |
| |
| /** |
| * Returns whether there are closed projects in the workspace that are |
| * not part of the current selection. |
| */ |
| private boolean hasOtherClosedProjects() { |
| //count the closed projects in the selection |
| int closedInSelection = 0; |
| Iterator resources = getSelectedResources().iterator(); |
| while (resources.hasNext()) { |
| IProject project = (IProject) resources.next(); |
| if (!project.isOpen()) |
| closedInSelection++; |
| } |
| //there are other closed projects if the selection does |
| //not contain all closed projects in the workspace |
| return closedInSelection < countClosedProjects(); |
| } |
| |
| protected void invokeOperation(IResource resource, IProgressMonitor monitor) throws CoreException { |
| ((IProject) resource).open(monitor); |
| } |
| |
| /** |
| * Returns the preference for whether to open required projects when opening |
| * a project. Consults the preference and prompts the user if necessary. |
| * |
| * @return <code>true</code> if referenced projects should be opened, and |
| * <code>false</code> otherwise. |
| */ |
| private boolean promptToOpenWithReferences() { |
| IPreferenceStore store = IDEWorkbenchPlugin.getDefault().getPreferenceStore(); |
| String key = IDEInternalPreferences.OPEN_REQUIRED_PROJECTS; |
| String value = store.getString(key); |
| if (MessageDialogWithToggle.ALWAYS.equals(value)) { |
| return true; |
| } |
| if (MessageDialogWithToggle.NEVER.equals(value)) { |
| return false; |
| } |
| String message = IDEWorkbenchMessages.OpenResourceAction_openRequiredProjects; |
| MessageDialogWithToggle dialog = MessageDialogWithToggle.openYesNoCancelQuestion(getShell(), IDEWorkbenchMessages.Question, message, null, false, store, key); |
| int result = dialog.getReturnCode(); |
| // the result is equal to SWT.DEFAULT if the user uses the 'esc' key to close the dialog |
| if (result == Window.CANCEL || result == SWT.DEFAULT) { |
| throw new OperationCanceledException(); |
| } |
| return dialog.getReturnCode() == IDialogConstants.YES_ID; |
| } |
| |
| /** |
| * Handles a resource changed event by updating the enablement if one of the |
| * selected projects is opened or closed. |
| */ |
| public void resourceChanged(IResourceChangeEvent event) { |
| // Warning: code duplicated in CloseResourceAction |
| List sel = getSelectedResources(); |
| // don't bother looking at delta if selection not applicable |
| if (selectionIsOfType(IResource.PROJECT)) { |
| IResourceDelta delta = event.getDelta(); |
| if (delta != null) { |
| IResourceDelta[] projDeltas = delta.getAffectedChildren(IResourceDelta.CHANGED); |
| for (int i = 0; i < projDeltas.length; ++i) { |
| IResourceDelta projDelta = projDeltas[i]; |
| if ((projDelta.getFlags() & IResourceDelta.OPEN) != 0) { |
| if (sel.contains(projDelta.getResource())) { |
| selectionChanged(getStructuredSelection()); |
| return; |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| /* |
| * (non-Javadoc) Method declared on IAction; overrides method on |
| * WorkspaceAction. |
| */ |
| public void run() { |
| try { |
| runOpenWithReferences(); |
| } catch (OperationCanceledException e) { |
| //just return when canceled |
| } |
| } |
| |
| /** |
| * Opens the selected projects, and all related projects, in the background. |
| */ |
| private void runOpenWithReferences() { |
| final List resources = new ArrayList(getActionResources()); |
| Job job = new WorkspaceJob(removeMnemonics(getText())) { |
| private boolean openProjectReferences = true; |
| private boolean hasPrompted = false; |
| /** |
| * Opens a project along with all projects it references |
| */ |
| private void doOpenWithReferences(IProject project, IProgressMonitor monitor) throws CoreException { |
| if (!project.exists() || project.isOpen()) { |
| return; |
| } |
| project.open(new SubProgressMonitor(monitor, 1000)); |
| final IProject[] references = project.getReferencedProjects(); |
| if (!hasPrompted) { |
| openProjectReferences = false; |
| for (int i = 0; i < references.length; i++) { |
| if (references[i].exists() && !references[i].isOpen()) { |
| openProjectReferences = true; |
| break; |
| } |
| } |
| if (openProjectReferences && hasOtherClosedProjects()) { |
| Display.getDefault().syncExec(new Runnable() { |
| public void run() { |
| openProjectReferences = promptToOpenWithReferences(); |
| //remember that we have prompted to avoid repeating the analysis |
| hasPrompted = true; |
| } |
| }); |
| } |
| } |
| |
| if (openProjectReferences) { |
| for (int i = 0; i < references.length; i++) { |
| doOpenWithReferences(references[i], monitor); |
| } |
| } |
| } |
| |
| public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException { |
| try { |
| // at most we can only open all projects currently closed |
| monitor.beginTask("", countClosedProjects() * 1000); //$NON-NLS-1$ |
| monitor.setTaskName(getOperationMessage()); |
| for (Iterator it = resources.iterator(); it.hasNext();) { |
| doOpenWithReferences((IProject) it.next(), monitor); |
| } |
| } finally { |
| monitor.done(); |
| } |
| return Status.OK_STATUS; |
| } |
| }; |
| job.setRule(ResourcesPlugin.getWorkspace().getRoot()); |
| job.setUser(true); |
| job.schedule(); |
| } |
| |
| /* |
| * (non-Javadoc) Method declared on WorkspaceAction. |
| */ |
| protected boolean shouldPerformResourcePruning() { |
| return false; |
| } |
| |
| /** |
| * The <code>OpenResourceAction</code> implementation of this |
| * <code>SelectionListenerAction</code> method ensures that this action is |
| * enabled only if one of the selections is a closed project. |
| */ |
| protected boolean updateSelection(IStructuredSelection s) { |
| // don't call super since we want to enable if closed project is |
| // selected. |
| |
| if (!selectionIsOfType(IResource.PROJECT)) { |
| return false; |
| } |
| |
| Iterator resources = getSelectedResources().iterator(); |
| while (resources.hasNext()) { |
| IProject currentResource = (IProject) resources.next(); |
| if (!currentResource.isOpen()) { |
| return true; |
| } |
| } |
| return false; |
| } |
| } |