diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/GeneratedMakefileBuilder.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/GeneratedMakefileBuilder.java index 42254346a1e..8abf172ffc8 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/GeneratedMakefileBuilder.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/GeneratedMakefileBuilder.java @@ -14,9 +14,11 @@ import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.Vector; import org.eclipse.cdt.core.CCorePlugin; @@ -28,13 +30,18 @@ import org.eclipse.cdt.core.model.ICModelMarker; import org.eclipse.cdt.core.resources.ACBuilder; import org.eclipse.cdt.core.resources.IConsole; import org.eclipse.cdt.managedbuilder.buildmodel.BuildDescriptionManager; +import org.eclipse.cdt.managedbuilder.buildmodel.IBuildCommand; import org.eclipse.cdt.managedbuilder.buildmodel.IBuildDescription; +import org.eclipse.cdt.managedbuilder.buildmodel.IBuildIOType; +import org.eclipse.cdt.managedbuilder.buildmodel.IBuildResource; +import org.eclipse.cdt.managedbuilder.buildmodel.IBuildStep; import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.envvar.IBuildEnvironmentVariable; import org.eclipse.cdt.managedbuilder.internal.buildmodel.DescriptionBuilder; import org.eclipse.cdt.managedbuilder.internal.buildmodel.IBuildModelBuilder; +import org.eclipse.cdt.managedbuilder.internal.buildmodel.StepBuilder; import org.eclipse.cdt.managedbuilder.macros.BuildMacroException; import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider; import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; @@ -312,6 +319,8 @@ public class GeneratedMakefileBuilder extends ACBuilder { protected Vector generationProblems; protected IProject[] referencedProjects; protected List resourcesToBuild; + private IConsole console; + private ConsoleOutputStream consoleOutStream; public static void outputTrace(String resourceName, String message) { if (VERBOSE) { System.out.println(TRACE_HEADER + resourceName + TRACE_FOOTER + message + NEWLINE); @@ -1315,4 +1324,321 @@ public class GeneratedMakefileBuilder extends ACBuilder { monitor.done(); } } + + /** + * Called to invoke the MBS Internal Builder for building the given resources in + * the given configuration + * + * This method is considered experimental. Clients implementing this API should expect + * possible changes in the API. + * + * @param cfg configuration to be built + * @param buildIncrementaly if true, incremental build will be performed, + * only files that need rebuild will be built. + * If false, full rebuild will be performed + * @param resumeOnErr if true, build will continue in case of error while building. + * If false the build will stop on the first error + * @param monitor Progress monitor. For every resource built this monitor will consume one unit of work. + */ + public void invokeInternalBuilder(IResource[] resourcesToBuild, IConfiguration cfg, + boolean buildIncrementaly, + boolean resumeOnErr, + boolean initNewConsole, + boolean printFinishedMessage, + IProgressMonitor monitor) { + // Get the project and make sure there's a monitor to cancel the build + IProject currentProject = cfg.getOwner().getProject(); + if (monitor == null) { + monitor = new NullProgressMonitor(); + } + + try { + int flags = 0; + IResourceDelta delta = null; + + if(buildIncrementaly){ + flags = BuildDescriptionManager.REBUILD | BuildDescriptionManager.REMOVED; + delta = getDelta(currentProject); + } + + + String[] msgs = new String[2]; + msgs[0] = ManagedMakeMessages.getResourceString(INTERNAL_BUILDER); + msgs[1] = currentProject.getName(); + + if(initNewConsole) + initNewBuildConsole(currentProject); + + StringBuffer buf = new StringBuffer(); + + if (initNewConsole) { + if (buildIncrementaly) + buf.append(ManagedMakeMessages.getResourceString("GeneratedMakefileBuilder.buildSelectedIncremental")); //$NON-NLS-1$ + else + buf.append(ManagedMakeMessages.getResourceString("GeneratedMakefileBuilder.buildSelectedRebuild")); //$NON-NLS-1$ + + + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + + buf.append(ManagedMakeMessages + .getResourceString(INTERNAL_BUILDER_HEADER_NOTE)); + buf.append("\n"); //$NON-NLS-1$ + } + + + if(!cfg.isSupported()){ + buf.append(ManagedMakeMessages.getFormattedString(WARNING_UNSUPPORTED_CONFIGURATION,new String[] {cfg.getName(),cfg.getToolChain().getName()})); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$ //$NON-NLS-2$ + } + consoleOutStream.write(buf.toString().getBytes()); + consoleOutStream.flush(); + + // Remove all markers for this project + // TODO remove only necessary markers + removeAllMarkers(currentProject); + + IBuildDescription des = BuildDescriptionManager.createBuildDescription(cfg, delta, flags); + + // Hook up an error parser manager + String[] errorParsers = cfg.getErrorParserList(); + ErrorParserManager epm = new ErrorParserManager(currentProject, des.getDefaultBuildDirLocation(), this, errorParsers); + epm.setOutputStream(consoleOutStream); + // This variable is necessary to ensure that the EPM stream stay open + // until we explicitly close it. See bug#123302. + OutputStream epmOutputStream = epm.getOutputStream(); + + boolean errorsFound = false; + + doneBuild: for (int k = 0; k < resourcesToBuild.length; k++) { + IBuildResource buildResource = des + .getBuildResource(resourcesToBuild[k]); + +// step collector + Set dependentSteps = new HashSet(); + +// get dependent IO types + IBuildIOType depTypes[] = buildResource.getDependentIOTypes(); + +// iterate through each type and add the step the type belongs to to the collector + for(int j = 0; j < depTypes.length; j++){ + IBuildIOType type = depTypes[j]; + if(type != null && type.getStep() != null) + dependentSteps.add(type.getStep()); + } + + monitor.subTask(ManagedMakeMessages.getResourceString("GeneratedMakefileBuilder.buildingFile") + resourcesToBuild[k].getProjectRelativePath()); //$NON-NLS-1$ + + // iterate through all build steps + Iterator stepIter = dependentSteps.iterator(); + + while(stepIter.hasNext()) + { + IBuildStep step = (IBuildStep) stepIter.next(); + + StepBuilder stepBuilder = new StepBuilder(step); + + int status = stepBuilder.build(consoleOutStream, epmOutputStream, new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK)); + + // Refresh the output resource without allowing the user to cancel. + // This is probably unkind, but short of this there is no way to ensure + // the UI is up-to-date with the build results + IBuildIOType[] outputIOTypes = step.getOutputIOTypes(); + + for(int j = 0; j < outputIOTypes.length; j++ ) + { + IBuildResource[] resources = outputIOTypes[j].getResources(); + + for(int i = 0; i < resources.length; i++) + { + IFile file = currentProject.getFile(resources[i].getLocation()); + file.refreshLocal(IResource.DEPTH_INFINITE, null); + } + } + + // check status + + switch (status) { + case IBuildModelBuilder.STATUS_OK: + // don't print anything if the step was successful, + // since the build might not be done as a whole + break; + case IBuildModelBuilder.STATUS_CANCELLED: + buf.append(ManagedMakeMessages + .getResourceString(BUILD_CANCELLED)); + break doneBuild; + case IBuildModelBuilder.STATUS_ERROR_BUILD: + errorsFound = true; + if (!resumeOnErr) { + buf.append(ManagedMakeMessages + .getResourceString(BUILD_STOPPED_ERR)); + break doneBuild; + } + break; + case IBuildModelBuilder.STATUS_ERROR_LAUNCH: + default: + buf.append(ManagedMakeMessages + .getResourceString(BUILD_FAILED_ERR)); + break doneBuild; + } + } + + + } + + // check status + // Report either the success or failure of our mission + buf = new StringBuffer(); + + + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ + + if (printFinishedMessage) { + if (errorsFound) { + buf.append(ManagedMakeMessages + .getResourceString(BUILD_FAILED_ERR)); + } else { + buf + .append(ManagedMakeMessages + .getResourceString("GeneratedMakefileBuilder.buildResourcesFinished")); //$NON-NLS-1$ + } + } + + // Write message on the console + consoleOutStream.write(buf.toString().getBytes()); + consoleOutStream.flush(); + epmOutputStream.close(); + + // Generate any error markers that the build has discovered + addBuilderMarkers(epm); + epm.reportProblems(); + consoleOutStream.close(); + } catch (Exception e) { + StringBuffer buf = new StringBuffer(); + String errorDesc = ManagedMakeMessages + .getResourceString(BUILD_ERROR); + buf.append(errorDesc); + buf.append(System.getProperty("line.separator", "\n")); //$NON-NLS-1$//$NON-NLS-2$ + buf.append("(").append(e.getLocalizedMessage()).append(")"); //$NON-NLS-1$ //$NON-NLS-2$ + + forgetLastBuiltState(); + } finally { + getGenerationProblems().clear(); + } + } + + private void removeAllMarkers(IFile file) { + IMarker[] markers; + try { + markers = file.findMarkers( + ICModelMarker.C_MODEL_PROBLEM_MARKER, true, + IResource.DEPTH_INFINITE); + } catch (CoreException e) { + // Handled just about every case in the sanity check + return; + } + if (markers != null) { + try { + file.getWorkspace().deleteMarkers(markers); + } catch (CoreException e) { + // The only situation that might cause this is some sort of + // resource change event + return; + } + } + } + + public void cleanFile(IFile file, IProgressMonitor monitor) { + + monitor.subTask("Cleaning output file(s) for " + + file.getProjectRelativePath()); + + // remove all markers on the file + removeAllMarkers(file); + + IProject currentProject = file.getProject(); + + IManagedBuildInfo info = ManagedBuildManager + .getBuildInfo(currentProject); + + // if we have no info then don't do anything + if (info == null) { + // monitor.worked(1); + return; + + } + + IConfiguration cfg = info.getDefaultConfiguration(); + + // figure out the output file for this file + IPath sourcePath = file.getProjectRelativePath(); + + int flags = BuildDescriptionManager.REBUILD | BuildDescriptionManager.REMOVED;; + IResourceDelta delta = getDelta(currentProject); + + try { + IBuildDescription des = BuildDescriptionManager + .createBuildDescription(cfg, delta, flags); + + IBuildResource buildResource = des.getBuildResource(file); + + // step collector + Set dependentSteps = new HashSet(); + + // get dependent IO types + IBuildIOType depTypes[] = buildResource.getDependentIOTypes(); + + // iterate through each type and add the step the type belongs to to + // the collector + for (int j = 0; j < depTypes.length; j++) { + IBuildIOType type = depTypes[j]; + if (type != null && type.getStep() != null) + dependentSteps.add(type.getStep()); + } + + // iterate through all build steps + Iterator stepIter = dependentSteps.iterator(); + + while (stepIter.hasNext()) { + IBuildStep step = (IBuildStep) stepIter.next(); + + // Delete the output resources + IBuildIOType[] outputIOTypes = step.getOutputIOTypes(); + + for (int j = 0; j < outputIOTypes.length; j++) { + IBuildResource[] resources = outputIOTypes[j] + .getResources(); + + for (int i = 0; i < resources.length; i++) { + IResource outputFile = currentProject + .findMember(resources[i].getFullPath().removeFirstSegments(1)); // strip project name + + if (outputFile != null) + outputFile.delete(true, new SubProgressMonitor( + monitor, 1)); + } + } + + } + + } catch (CoreException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + + /** + * @param currentProject + * @return + * @throws CoreException + */ + private void initNewBuildConsole(IProject currentProject) throws CoreException { + // Get a build console for the project + console = CCorePlugin.getDefault().getConsole(); + console.start(currentProject); + consoleOutStream = console.getOutputStream(); + } } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties index 5527f49ed2a..dfcf3119a00 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/PluginResources.properties @@ -104,6 +104,8 @@ UserDefinedMacroSupplier.storeOutputStream.wrong.arguments=Failed to persist mac # BuildMacroStatus messages BuildMacroStatus.status.macro.undefined=Macro {0} is undefined +BuildFilesAction.buildingSelectedFiles=Building Selected Files +BuildFilesAction.buildSelectedFile=Build the selected file. BuildMacroStatus.status.reference.eachother=Macros {0} and {1} reference each other BuildMacroStatus.status.reference.incorrect=Macro {0} reference is incorrect BuildMacroStatus.status.macro.not.string=Macro {0} is not of String type @@ -116,6 +118,16 @@ ResourceChangeHandler.buildInfoSerializationJob=Build Info Serialization #ManagedBuilderCorePlugin messages ManagedBuilderCorePlugin.resourceChangeHandlingInitializationJob=Initializing Resource Change Handling +GeneratedMakefileBuilder.buildResourcesFinished=Build of selected resources is complete. +GeneratedMakefileBuilder.buildSelectedIncremental=Building selected file(s) incrementally +GeneratedMakefileBuilder.buildSelectedRebuild=Rebuilding selected file(s) +GeneratedMakefileBuilder.buildingFile=Building file +BuildFilesAction.building=Building +BuildFilesAction.buildFiles=Build File(s) +ManagedBuilderCorePlugin.resourceChangeHandlingInitializationJob=Initializing Resource Change Handling #Internal Builder messages -InternalBuilder.msg.header=Internal Builder: {0} \ No newline at end of file +InternalBuilder.msg.header=Internal Builder: {0} +CleanFilesAction.cleanFiles=Clean File(s) +CleanFilesAction.cleanSelectedFiles=Clean the selected file(s). +CleanFilesAction.cleaningFiles=Cleaning files diff --git a/build/org.eclipse.cdt.managedbuilder.ui/plugin.properties b/build/org.eclipse.cdt.managedbuilder.ui/plugin.properties index befc5db8906..3b1807cc8a6 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/plugin.properties +++ b/build/org.eclipse.cdt.managedbuilder.ui/plugin.properties @@ -36,3 +36,10 @@ BuildConfigToolbarAction.label=Active Build Configuration BuildConfigMenuAction.label=Active Buil&d Configuration BuildConfigContextAction.label=Active Bui&ld Configuration BuildConfigAction.tooltip=Change active build configuration for the current project + +# Build/clean selected files actions +BuildSelectedFiles.label=Build F&ile(s) +CleanSelectedFiles.label=Cl&ean File(s) +BuildSelectedFilesActionSet.label=Build/Clean Selected File(s) +BuildSelectedFiles.tooltip=Rebuilds the selected file(s) including all dependencies +CleanSelectedFiles.tooltip=Cleans the output file(s) for the selected file(s) \ No newline at end of file diff --git a/build/org.eclipse.cdt.managedbuilder.ui/plugin.xml b/build/org.eclipse.cdt.managedbuilder.ui/plugin.xml index 4b3b31837ed..cf59f749e66 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/plugin.xml +++ b/build/org.eclipse.cdt.managedbuilder.ui/plugin.xml @@ -147,6 +147,27 @@ style="pulldown" tooltip="%BuildConfigAction.tooltip"/> + + + + @@ -166,6 +187,23 @@ name="projectNature" value="org.eclipse.cdt.managedbuilder.core.managedBuildNature"/> + + + + diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/actions/BuildFilesAction.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/actions/BuildFilesAction.java new file mode 100644 index 00000000000..933ba44cd86 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/actions/BuildFilesAction.java @@ -0,0 +1,291 @@ +/******************************************************************************* + * Copyright (c) 2006 Texas Instruments Incorporated 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: + * Texas Instruments - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.ui.actions; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; +import org.eclipse.ui.PlatformUI; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.internal.core.GeneratedMakefileBuilder; +import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.ISelectionService; + +/** + * @author crecoskie + * + */ +public class BuildFilesAction extends Action implements IWorkbenchWindowActionDelegate { + + /** + * The workbench window; or null if this action has been + * disposed. + */ + private IWorkbenchWindow workbenchWindow; + + /** + * + */ + public BuildFilesAction() { + this(PlatformUI.getWorkbench().getActiveWorkbenchWindow()); + } + + /** + * Creates an instance of this action, for use in the given window. + */ + public BuildFilesAction(IWorkbenchWindow window) { + super(ManagedMakeMessages.getResourceString("BuildFilesAction.buildFiles")); //$NON-NLS-1$ + if (window == null) { + throw new IllegalArgumentException(); + } + this.workbenchWindow = window; + setToolTipText(ManagedMakeMessages.getResourceString("BuildFilesAction.buildSelectedFile")); //$NON-NLS-1$ + setActionDefinitionId("org.eclipse.cdt.managedbuilder.ui.BuildFilesAction"); //$NON-NLS-1$ + } + + /** + * @param text + */ + public BuildFilesAction(String text) { + super(text); + // TODO Auto-generated constructor stub + } + + /** + * @param text + * @param image + */ + public BuildFilesAction(String text, ImageDescriptor image) { + super(text, image); + // TODO Auto-generated constructor stub + } + + /** + * @param text + * @param style + */ + public BuildFilesAction(String text, int style) { + super(text, style); + // TODO Auto-generated constructor stub + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose() + */ + public void dispose() { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow) + */ + public void init(IWorkbenchWindow window) { + workbenchWindow = window; + + } + + /** + * Helper method that converts an object to the IFile + * interface. The conversion is a bare cast operation (if the object is + * instance of IFile, or an adaptation (if the object is + * instance of IAdaptable). + * + * @param object + * the object to be cast to IFile + * @return a reference to an IFile corresponding to the object provided, or + * null if it is not possible to convert the provided object to + * IFile. + */ + private IFile convertToIFile(Object object) { + + if (object instanceof IFile) { + return (IFile) object; + } + + if (object instanceof IAdaptable) { + IAdaptable adaptable = (IAdaptable) object; + IFile file = (IFile) adaptable.getAdapter(IFile.class); + + if (file != null) { + return file; + } + } + + // this *should* be redundant now that I've made CElement adaptable to IFile but we'll leave + // it just to be safe + if (object instanceof ITranslationUnit) { + IResource resource = ((ITranslationUnit) object).getResource(); + + // should be safe to cast to IFile (can't really have a non-file + // translation unit), but check anyway + if (resource instanceof IFile) { + return (IFile) resource; + } + + } + + return null; + } + + /** + * Returns a list of resources currently selected. + * "Buildable" means buildable by MBS. + * + * @return a list of resources + */ + private List getSelectedBuildableFiles() { + + List files = new LinkedList(); + + ISelectionService selectionService = workbenchWindow + .getSelectionService(); + ISelection selection = selectionService.getSelection(); + + if (selection instanceof IStructuredSelection) { + IStructuredSelection structuredSelection = (IStructuredSelection) selection; + for (Iterator elements = structuredSelection.iterator(); elements + .hasNext();) { + IFile file = convertToIFile(elements.next()); + if (file != null) { + // we only add files that we can actually build + IManagedBuildInfo buildInfo = ManagedBuildManager + .getBuildInfo(file.getProject()); + + if (buildInfo.buildsFileType(file.getFileExtension())) { + files.add(file); + } + } + } + + // since we don't allow building folders, there can be no + // redundancies + // eliminateRedundancies(resources); + } + + return files; + } + + + private static final class BuildFilesJob extends Job { + private final List files; + + BuildFilesJob(List filesToBuild) + { + super(ManagedMakeMessages.getResourceString("BuildFilesAction.buildingSelectedFiles")); //$NON-NLS-1$ + + files = filesToBuild; + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) + */ + protected IStatus run(IProgressMonitor monitor) { + + Iterator iterator = files.iterator(); + + GeneratedMakefileBuilder builder = new GeneratedMakefileBuilder(); + + monitor.beginTask(ManagedMakeMessages.getResourceString("BuildFilesAction.building"), files.size()); //$NON-NLS-1$ + + boolean isFirstFile = true; + + while(iterator.hasNext()) + { + IFile file = (IFile) iterator.next(); + + IManagedBuildInfo buildInfo = ManagedBuildManager + .getBuildInfo(file.getProject()); + + IResource[] resources = {file}; + + // invoke the internal builder to do the build + builder.invokeInternalBuilder(resources, buildInfo + .getDefaultConfiguration(), false, false, isFirstFile, + !iterator.hasNext(), monitor); + + if(isFirstFile) { + isFirstFile = false; + } + + if(monitor.isCanceled()) + { + return Status.CANCEL_STATUS; + } + + + } + + monitor.done(); + return Status.OK_STATUS; + } + + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.jobs.Job#belongsTo(java.lang.Object) + */ + public boolean belongsTo(Object family) { + return ResourcesPlugin.FAMILY_MANUAL_BUILD == family; + } + + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) + */ + public void run(IAction action) { + + List selectedFiles = getSelectedBuildableFiles(); + + Job buildFilesJob = new BuildFilesJob(selectedFiles); + + buildFilesJob.schedule(); + + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, + * org.eclipse.jface.viewers.ISelection) + */ + public void selectionChanged(IAction action, ISelection selection) { + // TODO Auto-generated method stub + + } + + + +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/actions/CleanFilesAction.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/actions/CleanFilesAction.java new file mode 100644 index 00000000000..81d4a3e046b --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/ui/actions/CleanFilesAction.java @@ -0,0 +1,301 @@ +/******************************************************************************* + * Copyright (c) 2006 Texas Instruments Incorporated 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: + * Texas Instruments - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.managedbuilder.ui.actions; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Vector; + +import org.eclipse.cdt.core.model.ICModelMarker; +import org.eclipse.cdt.core.model.ITranslationUnit; +import org.eclipse.cdt.managedbuilder.buildmodel.BuildDescriptionManager; +import org.eclipse.cdt.managedbuilder.buildmodel.IBuildDescription; +import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; +import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; +import org.eclipse.cdt.managedbuilder.internal.core.GeneratedMakefileBuilder; +import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.ui.ISelectionService; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; +import org.eclipse.ui.PlatformUI; + +/** + * @author crecoskie + * + */ +public class CleanFilesAction extends Action implements IWorkbenchWindowActionDelegate { + /** + * The workbench window; or null if this action has been + * disposed. + */ + private IWorkbenchWindow workbenchWindow; + + /** + * + */ + public CleanFilesAction() { + this(PlatformUI.getWorkbench().getActiveWorkbenchWindow()); + } + + /** + * Creates an instance of this action, for use in the given window. + */ + public CleanFilesAction(IWorkbenchWindow window) { + super(ManagedMakeMessages.getResourceString("CleanFilesAction.cleanFiles")); //$NON-NLS-1$ + if (window == null) { + throw new IllegalArgumentException(); + } + this.workbenchWindow = window; + setToolTipText(ManagedMakeMessages.getResourceString("CleanFilesAction.cleanSelectedFiles")); //$NON-NLS-1$ + setActionDefinitionId("org.eclipse.cdt.managedbuilder.ui.CleanFilesAction"); //$NON-NLS-1$ + } + + /** + * @param text + */ + public CleanFilesAction(String text) { + super(text); + // TODO Auto-generated constructor stub + } + + /** + * @param text + * @param image + */ + public CleanFilesAction(String text, ImageDescriptor image) { + super(text, image); + // TODO Auto-generated constructor stub + } + + /** + * @param text + * @param style + */ + public CleanFilesAction(String text, int style) { + super(text, style); + // TODO Auto-generated constructor stub + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose() + */ + public void dispose() { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow) + */ + public void init(IWorkbenchWindow window) { + workbenchWindow = window; + + } + + /** + * Helper method that converts an object to the IFile + * interface. The conversion is a bare cast operation (if the object is + * instance of IFile, or an adaptation (if the object is + * instance of IAdaptable). + * + * @param object + * the object to be cast to IFile + * @return a reference to an IFile corresponding to the object provided, or + * null if it is not possible to convert the provided object to + * IFile. + */ + private IFile convertToIFile(Object object) { + + if (object instanceof IFile) + return (IFile) object; + + if (object instanceof IAdaptable) { + IAdaptable adaptable = (IAdaptable) object; + IFile file = (IFile) adaptable.getAdapter(IFile.class); + + if (file != null) { + return file; + } + } + + // this *should* be redundant now that I've made CElement adaptable to IFile but we'll leave + // it just to be safe + if (object instanceof ITranslationUnit) { + IResource resource = ((ITranslationUnit) object).getResource(); + + // should be safe to cast to IFile (can't really have a non-file + // translation unit), but check anyway + if (resource instanceof IFile) { + return (IFile) resource; + } + + } + + return null; + } + + /** + * Returns a list of buildable resources currently selected. + * "Buildable" means buildable by MBS. + * + * @return a list of resources + */ + private List getSelectedBuildableFiles() { + + List files = new LinkedList(); + + ISelectionService selectionService = workbenchWindow + .getSelectionService(); + ISelection selection = selectionService.getSelection(); + + if (selection instanceof IStructuredSelection) { + IStructuredSelection structuredSelection = (IStructuredSelection) selection; + for (Iterator elements = structuredSelection.iterator(); elements + .hasNext();) { + IFile file = convertToIFile(elements.next()); + if (file != null) { + // we only add files that we can actually build + IManagedBuildInfo buildInfo = ManagedBuildManager + .getBuildInfo(file.getProject()); + + if (buildInfo.buildsFileType(file.getFileExtension())) { + files.add(file); + } + } + } + + // since we don't allow building folders, there can be no + // redundancies + // eliminateRedundancies(resources); + } + + return files; + } + + private static final class CleanFilesJob extends Job { + private final List files; + + protected Vector generationProblems; + + private CleanFilesJob(String name, List filesToBuild) { + super(name); + files = filesToBuild; + } + + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor) + */ + protected IStatus run(IProgressMonitor monitor) { + synchronized (getClass()) { + if (monitor.isCanceled()) { + return Status.CANCEL_STATUS; + } + Job[] buildJobs = Platform.getJobManager().find( + ResourcesPlugin.FAMILY_MANUAL_BUILD); + for (int i = 0; i < buildJobs.length; i++) { + Job curr = buildJobs[i]; + if (curr != this && curr instanceof CleanFilesJob) { + curr.cancel(); // cancel all other build jobs of our + // kind + + } + } + } + try { + if (files != null) { + monitor.beginTask(ManagedMakeMessages.getResourceString("CleanFilesAction.cleaningFiles"), files.size()); //$NON-NLS-1$ + + Iterator iterator = files.iterator(); + + // clean each file + while (iterator.hasNext() && !monitor.isCanceled()) { + IFile file = (IFile) iterator.next(); + + GeneratedMakefileBuilder builder = new GeneratedMakefileBuilder(); + builder.cleanFile(file, monitor); + + if(monitor.isCanceled()) + { + return Status.CANCEL_STATUS; + } + } + + monitor.done(); + + } + } catch (OperationCanceledException e) { + return Status.CANCEL_STATUS; + } finally { + monitor.done(); + } + return Status.OK_STATUS; + } + + public boolean belongsTo(Object family) { + return ResourcesPlugin.FAMILY_MANUAL_BUILD == family; + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) + */ + public void run(IAction action) { + + List selectedFiles = getSelectedBuildableFiles(); + + CleanFilesJob job = new CleanFilesJob(ManagedMakeMessages.getResourceString("CleanFilesAction.cleaningFiles"), selectedFiles); //$NON-NLS-1$ + + job.schedule(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, + * org.eclipse.jface.viewers.ISelection) + */ + public void selectionChanged(IAction action, ISelection selection) { + // TODO Auto-generated method stub + + } + +} diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CElement.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CElement.java index 5239594c358..1718f2aa529 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CElement.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CElement.java @@ -29,6 +29,7 @@ import org.eclipse.cdt.core.model.ISourceRange; import org.eclipse.cdt.core.model.ISourceReference; import org.eclipse.cdt.core.model.ISourceRoot; import org.eclipse.cdt.core.model.IWorkingCopy; +import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourceAttributes; import org.eclipse.core.runtime.CoreException; @@ -52,6 +53,19 @@ public abstract class CElement extends PlatformObject implements ICElement { fType= type; } + /* (non-Javadoc) + * @see org.eclipse.core.runtime.PlatformObject#getAdapter(java.lang.Class) + */ + public Object getAdapter(Class adapter) { + if(adapter == IFile.class) + return (IFile) getUnderlyingResource(); + if(adapter == IResource.class) + return getUnderlyingResource(); + else + return super.getAdapter(adapter); + } + + // setters public void setElementType (int type) {