diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/launching/CMainTab.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/launching/CMainTab.java index a04b282ed2a..f6be013d9b3 100644 --- a/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/launching/CMainTab.java +++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb.ui/src/org/eclipse/cdt/dsf/gdb/internal/ui/launching/CMainTab.java @@ -314,7 +314,7 @@ public class CMainTab extends CLaunchConfigurationTab { */ public void performApply(ILaunchConfigurationWorkingCopy config) { ICProject cProject = this.getCProject(); - if (cProject != null) + if (cProject != null && cProject.exists()) { config.setMappedResources(new IResource[] { cProject.getProject() }); try { // Only initialize the build config ID once. @@ -660,6 +660,9 @@ public class CMainTab extends CLaunchConfigurationTab { if (cElement != null) { initializeCProject(cElement, config); initializeProgramName(cElement, config); + } else { + // don't want to remember the interim value from before + config.setMappedResources(null); } } diff --git a/launch/org.eclipse.cdt.launch/META-INF/MANIFEST.MF b/launch/org.eclipse.cdt.launch/META-INF/MANIFEST.MF index c189dadfbd3..0070c40d537 100644 --- a/launch/org.eclipse.cdt.launch/META-INF/MANIFEST.MF +++ b/launch/org.eclipse.cdt.launch/META-INF/MANIFEST.MF @@ -21,7 +21,8 @@ Require-Bundle: org.eclipse.ui.ide;bundle-version="[3.2.0,4.0.0)", org.eclipse.cdt.debug.core;bundle-version="[6.0.0,7.0.0)", org.eclipse.cdt.debug.ui;bundle-version="[6.0.0,7.0.0)", org.eclipse.core.runtime;bundle-version="[3.2.0,4.0.0)", - org.eclipse.core.variables;bundle-version="[3.1.100,4.0.0)" + org.eclipse.core.variables;bundle-version="[3.1.100,4.0.0)", + org.eclipse.ltk.core.refactoring;bundle-version="[3.5.0,4.0.0)" Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: J2SE-1.5 Import-Package: com.ibm.icu.text diff --git a/launch/org.eclipse.cdt.launch/plugin.properties b/launch/org.eclipse.cdt.launch/plugin.properties index 2b71645fa34..1763742e7ff 100644 --- a/launch/org.eclipse.cdt.launch/plugin.properties +++ b/launch/org.eclipse.cdt.launch/plugin.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2005, 2007 QNX Software Systems and others. +# Copyright (c) 2005, 2009 QNX Software Systems 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 @@ -29,3 +29,4 @@ CommonLaunchTab.name=Common CoreFileLaunchTab.name=Debugger RefreshLaunchTab.name=Refresh +resourceRenameParticipant.name=C/C++ Launch Configuration Rename Participant diff --git a/launch/org.eclipse.cdt.launch/plugin.xml b/launch/org.eclipse.cdt.launch/plugin.xml index d9f4339b258..f2ac1f53c47 100644 --- a/launch/org.eclipse.cdt.launch/plugin.xml +++ b/launch/org.eclipse.cdt.launch/plugin.xml @@ -229,4 +229,35 @@ id="org.eclipse.cdt.launch.launchGroup.image"> + + + + + + + + + + + + + + + + + + + + diff --git a/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/refactoring/AbstractLaunchConfigChange.java b/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/refactoring/AbstractLaunchConfigChange.java new file mode 100644 index 00000000000..bbb5df17347 --- /dev/null +++ b/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/refactoring/AbstractLaunchConfigChange.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2009 QNX Software Systems 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: + * QNX Software Systems - Initial API and implementation9 + *******************************************************************************/ + +package org.eclipse.cdt.launch.internal.refactoring; + +import org.eclipse.cdt.launch.internal.ui.LaunchMessages; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.CompositeChange; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; + +/** + * Common implementation of launch configuration changes. + * + * @author Christian W. Damus (cdamus) + * + * @since 6.0 + * + */ +public abstract class AbstractLaunchConfigChange extends Change { + + private ILaunchConfiguration launchConfig; + + /** + * Initializes me with the launch configuration that I change. + * + * @param launchConfig + * my launch configuration + */ + public AbstractLaunchConfigChange(ILaunchConfiguration launchConfig) { + this.launchConfig = launchConfig; + } + + protected ILaunchConfiguration getLaunchConfiguration() { + return launchConfig; + } + + @Override + public Object getModifiedElement() { + return getLaunchConfiguration(); + } + + @Override + public void initializeValidationData(IProgressMonitor pm) { + // no-op + } + + @Override + public RefactoringStatus isValid(IProgressMonitor pm) throws CoreException, + OperationCanceledException { + + return new RefactoringStatus(); + } + + /** + * Chains changes, creating new composites or appending to existing composites, as appropriate. + * The pattern of usage is: + *
+	 *   Change change = null;
+	 *   
+	 *   for (whatever) {
+	 *       change = AbstractLaunchConfigChange.append(change, createNextChange(...));
+	 *   }
+	 *   
+	 *   // do something with the change
+	 * 
+ * + * @param change a change to add to, or null to start a new (potentially conposite) change + * @param toAppend the change to add. Must not be null + * + * @return the resulting change, which may or may not be a composite + */ + public static Change append(Change change, Change toAppend) { + if (change == null) { + return toAppend; + } else if (change instanceof CompositeChange) { + ((CompositeChange) change).add(toAppend); + return change; + } else { + return new CompositeChange(LaunchMessages.getString("AbstractChange.compositeName0"), //$NON-NLS-1$ + new Change[] { change, toAppend }); + } + } +} diff --git a/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/refactoring/ProjectRenameChange.java b/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/refactoring/ProjectRenameChange.java new file mode 100644 index 00000000000..baec869e0bb --- /dev/null +++ b/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/refactoring/ProjectRenameChange.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (c) 2009 QNX Software Systems 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: + * QNX Software Systems - Initial API and implementation9 + *******************************************************************************/ + +package org.eclipse.cdt.launch.internal.refactoring; + +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.cdt.launch.internal.ui.LaunchMessages; +import org.eclipse.cdt.launch.internal.ui.LaunchUIPlugin; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.MultiStatus; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.osgi.util.NLS; + +/** + * A change to update a launch configuration with a new project name. + * + * @author Christian W. Damus (cdamus) + * + * @since 6.0 + */ +class ProjectRenameChange extends AbstractLaunchConfigChange { + + private String changeName; + + private String oldName; + private String newName; + + /** + * Initializes me. + * + * @param launchConfig + * the launch configuration that I change + * @param oldName + * the old project name + * @param newName + * the new project name + */ + public ProjectRenameChange(ILaunchConfiguration launchConfig, + String oldName, String newName) { + super(launchConfig); + + this.oldName = oldName; + this.newName = newName; + } + + @Override + public String getName() { + if (changeName == null) { + changeName = NLS.bind(LaunchMessages.getString("ProjectRenameChange.name"), //$NON-NLS-1$ + getLaunchConfiguration().getName()); + } + + return changeName; + } + + @Override + public Change perform(IProgressMonitor pm) throws CoreException { + + ILaunchConfiguration launchConfig = getLaunchConfiguration(); + ILaunchConfigurationWorkingCopy copy = launchConfig.getWorkingCopy(); + + IResource[] mapped = launchConfig.getMappedResources(); + + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + IProject oldProject = root.getProject(oldName); + IProject newProject = root.getProject(newName); + + if ((oldProject != null) && (newProject != null)) { + if ((mapped != null) && (mapped.length > 0)) { + for (int i = 0; i < mapped.length; i++) { + if (oldProject.equals(mapped[i])) { + mapped[i] = newProject; + } + } + + copy.setMappedResources(mapped); + } + } + + copy.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, + newName); + + try { + copy.doSave(); + } catch (CoreException e) { + LaunchUIPlugin.log(new MultiStatus(LaunchUIPlugin.PLUGIN_ID, 0, + new IStatus[] { e.getStatus() }, NLS.bind( + LaunchMessages.getString("ProjectRenameChange.saveFailed"), //$NON-NLS-1$ + launchConfig.getName()), null)); + return null; // not undoable, as we didn't effect our change + } + + return new ProjectRenameChange(getLaunchConfiguration(), newName, + oldName); + } + +} diff --git a/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/refactoring/ResourceRenameParticipant.java b/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/refactoring/ResourceRenameParticipant.java new file mode 100644 index 00000000000..4451ec320d8 --- /dev/null +++ b/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/refactoring/ResourceRenameParticipant.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * Copyright (c) 2009 QNX Software Systems 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: + * QNX Software Systems - Initial API and implementation9 + *******************************************************************************/ + +package org.eclipse.cdt.launch.internal.refactoring; + +import java.util.Collection; +import java.util.Set; + +import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExecutableExtension; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationType; +import org.eclipse.debug.core.ILaunchManager; +import org.eclipse.ltk.core.refactoring.Change; +import org.eclipse.ltk.core.refactoring.RefactoringStatus; +import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext; +import org.eclipse.ltk.core.refactoring.participants.RenameParticipant; + +/** + * A rename participant for resource refactorings, that updates affected CDT + * launch configurations. + * + * @author Christian W. Damus (cdamus) + * + * @since 6.0 + */ +public class ResourceRenameParticipant extends RenameParticipant implements + IExecutableExtension { + + private String name; + + private IResource resourceBeingRenamed; + + /** + * Initializes me. + */ + public ResourceRenameParticipant() { + super(); + } + + @Override + public String getName() { + return name; + } + + @Override + protected boolean initialize(Object element) { + if (element instanceof IResource) { + resourceBeingRenamed = (IResource) element; + } else if (element instanceof IAdaptable) { + resourceBeingRenamed = (IResource) ((IAdaptable) element) + .getAdapter(IResource.class); + } + + return true; + } + + @Override + public Change createChange(IProgressMonitor pm) throws CoreException, + OperationCanceledException { + + Change result = null; + + if (resourceBeingRenamed instanceof IProject) { + String oldName = resourceBeingRenamed.getName(); + String newName = getArguments().getNewName(); + Collection launchTypes = getCLaunchConfigTypes(); + + if (!launchTypes.isEmpty()) { + ILaunchManager mgr = DebugPlugin.getDefault() + .getLaunchManager(); + + for (ILaunchConfigurationType type : launchTypes) { + ILaunchConfiguration[] launches = mgr + .getLaunchConfigurations(type); + + for (ILaunchConfiguration next : launches) { + if (next + .getAttribute( + ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, + "").equals(oldName)) { //$NON-NLS-1$ + + result = AbstractLaunchConfigChange.append(result, + new ProjectRenameChange(next, oldName, + newName)); + } + } + } + } + } + + return result; + } + + static Collection getCLaunchConfigTypes() { + Set result = new java.util.HashSet(); + + ILaunchManager mgr = DebugPlugin.getDefault().getLaunchManager(); + for (ILaunchConfigurationType next : mgr.getLaunchConfigurationTypes()) { + // is it a CDT launch type? + if (next.getPluginIdentifier().startsWith("org.eclipse.cdt.")) { //$NON-NLS-1$ + result.add(next); + } + } + + return result; + } + + @Override + public RefactoringStatus checkConditions(IProgressMonitor pm, + CheckConditionsContext context) throws OperationCanceledException { + + // I have no conditions to check. Updating the launches is trivial + return new RefactoringStatus(); + } + + public void setInitializationData(IConfigurationElement config, + String propertyName, Object data) throws CoreException { + + this.name = config.getAttribute("name"); //$NON-NLS-1$ + } + +} diff --git a/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/ui/LaunchMessages.properties b/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/ui/LaunchMessages.properties index e6fdd81141a..b81f8ef079b 100644 --- a/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/ui/LaunchMessages.properties +++ b/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/internal/ui/LaunchMessages.properties @@ -54,6 +54,7 @@ CoreFileLaunchDelegate.postmortem_debugging_failed=Post-mortem debugging failed AbstractCDebuggerTab.No_debugger_available=No debugger available AbstractCDebuggerTab.Debugger=Debugger AbstractCDebuggerTab.ErrorLoadingDebuggerPage=Error Loading Debugger UI Component. +AbstractChange.compositeName0=Update C/C++ launch configurations LaunchUIPlugin.Error=Error @@ -165,3 +166,5 @@ MultiLaunchConfigurationTabGroup.7=Mode MultiLaunchConfigurationTabGroup.8=Select Launch Configuration MultiLaunchConfigurationTabGroup.9=Edit Launch Configuration MultiLaunchConfigurationTabGroup.10=Launches +ProjectRenameChange.name=Update launch configuration "{0}" +ProjectRenameChange.saveFailed=Failed to save updated launch configuration "{0}" diff --git a/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/ui/CMainTab.java b/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/ui/CMainTab.java index d4e7e41f03a..aa803220992 100644 --- a/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/ui/CMainTab.java +++ b/launch/org.eclipse.cdt.launch/src/org/eclipse/cdt/launch/ui/CMainTab.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2008 QNX Software Systems and others. + * Copyright (c) 2005, 2009 QNX Software Systems 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 @@ -374,10 +374,16 @@ public class CMainTab extends CLaunchConfigurationTab { */ public void performApply(ILaunchConfigurationWorkingCopy config) { ICProject cProject = this.getCProject(); - if (cProject != null) + if (cProject != null && cProject.exists()) { config.setMappedResources(new IResource[] { cProject.getProject() }); } + else + { + // the user typed in a non-existent project name. Ensure that + // won't be suppressed from the dialog. This matches JDT behaviour + config.setMappedResources(null); + } config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME, fProjText.getText()); config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_BUILD_CONFIG_ID, (String)fBuildConfigCombo.getData(Integer.toString(fBuildConfigCombo.getSelectionIndex()))); config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, fProgText.getText()); @@ -706,6 +712,9 @@ public class CMainTab extends CLaunchConfigurationTab { if (cElement != null) { initializeCProject(cElement, config); initializeProgramName(cElement, config); + } else { + // don't want to remember the interim value from before + config.setMappedResources(null); } if (wantsTerminalOption()) { config.setAttribute(ICDTLaunchConfigurationConstants.ATTR_USE_TERMINAL, ICDTLaunchConfigurationConstants.USE_TERMINAL_DEFAULT);