Changeset 1175
- Timestamp:
- 05/25/08 06:40:06 (3 months ago)
- Files:
-
- trunk/descent.building/.settings (added)
- trunk/descent.building/.settings/org.eclipse.jdt.core.prefs (added)
- trunk/descent.building/src/descent/building/IDescentBuilderConstants.java (modified) (1 diff)
- trunk/descent.building/src/descent/internal/building/BuilderUtil.java (added)
- trunk/descent.building/src/descent/internal/building/debuild/DebuildBuilder.java (modified) (4 diffs)
- trunk/descent.building/src/descent/internal/building/debuild/ObjectFile.java (modified) (3 diffs)
- trunk/descent.building/src/descent/internal/building/debuild/RecursiveDependancyCollector.java (modified) (2 diffs)
- trunk/descent.building/src/descent/internal/building/debuild/Util.java (deleted)
- trunk/descent.building/src/descent/internal/building/ui/AbstractBuilderTab.java (modified) (8 diffs)
- trunk/descent.building/src/descent/internal/building/ui/CompilerTab.java (modified) (8 diffs)
- trunk/descent.building/src/descent/internal/building/ui/DebuildTabGroup.java (modified) (1 diff)
- trunk/descent.building/src/descent/internal/building/ui/GeneralTab.java (moved) (moved from trunk/descent.building/src/descent/internal/building/ui/BuildTab.java) (14 diffs)
- trunk/descent.launching/META-INF/MANIFEST.MF (modified) (1 diff)
- trunk/descent.unittest/flute/src/org/dsource/descent/flute/fauxmain.d (added)
- trunk/descent.unittest/flute/src/org/dsource/descent/flute/flute-old.d (deleted)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/descent.building/src/descent/building/IDescentBuilderConstants.java
r1174 r1175 65 65 */ 66 66 public static final String ATTR_COMPILER_ID = "descent.building.debuild.compiler_id"; 67 68 /** 69 * Specifies the target output type. Must be one of {@link #OUTPUT_TYPE_EXECUTABLE} 70 * or {@link #OUTPUT_TYPE_STATIC_LIBRARY}. Support may be added in the future for 71 * OS dynamic libraries (.dll/.so) and/or DDL. 72 * 73 * Type: String 74 */ 75 public static final String ATTR_OUTPUT_TYPE = "descent.building.debuild.output_type"; 76 77 /** 78 * Specifies the target output file location. 79 * 80 * Type: String 81 */ 82 public static final String ATTR_OUTPUT_FILE = "descent.building.debuild.output_file"; 83 84 /** 85 * Constant used for {@link #ATTR_OUTPUT_TYPE} to specify the output target 86 * should be an executable file. 87 */ 88 public static final String OUTPUT_TYPE_EXECUTABLE = "executable"; 89 90 /** 91 * Constant used for {@link #ATTR_OUTPUT_TYPE} to specify the output target 92 * should be a static library (.lib or .a) 93 */ 94 public static final String OUTPUT_TYPE_STATIC_LIBRARY = "static_library"; 67 95 } trunk/descent.building/src/descent/internal/building/debuild/DebuildBuilder.java
r1174 r1175 17 17 import descent.core.IJavaProject; 18 18 import descent.core.JavaModelException; 19 import descent.internal.building.BuilderUtil; 19 20 import descent.building.IDBuilder; 20 21 import descent.building.compiler.BuildError; … … 156 157 case IClasspathEntry.CPE_SOURCE: 157 158 case IClasspathEntry.CPE_LIBRARY: 158 importPath.add(new File( Util.getAbsolutePath(entry.getPath())));159 importPath.add(new File(BuilderUtil.getAbsolutePath(entry.getPath()))); 159 160 break; 160 161 case IClasspathEntry.CPE_PROJECT: … … 191 192 ICompilerInterface compilerInterface = req.getCompilerInterface(); 192 193 IJavaProject project = req.getProject(); 193 String workingDirectory = Util.getAbsolutePath(project.getOutputLocation());194 String workingDirectory = BuilderUtil.getAbsolutePath(project.getOutputLocation()); 194 195 File outputDirectory = new File(workingDirectory); 195 196 … … 298 299 return EXECUTABLE_FILE_PREFIX + 299 300 System.currentTimeMillis() + 300 (Util.isWindows() ? 301 ".exe" : 302 ""); 301 BuilderUtil.EXTENSION_EXECUTABLE; 303 302 } 304 303 } trunk/descent.building/src/descent/internal/building/debuild/ObjectFile.java
r1174 r1175 15 15 import descent.core.IJavaProject; 16 16 import descent.core.JavaModelException; 17 import descent.internal.building.BuilderUtil; 17 18 import descent.internal.building.BuildingPlugin; 18 19 … … 337 338 private String getExtension() 338 339 { 339 return Util.isWindows() ? ".obj" : ".o"; 340 } 341 342 public static void main(String[] args) 343 { 344 for(Entry<Object, Object> prop : System.getProperties().entrySet()) 345 System.out.format("%1$s = %2$s\n", prop.getKey(), prop.getValue()); 340 return BuilderUtil.EXTENSION_OBJECT_FILE; 346 341 } 347 342 … … 350 345 try 351 346 { 352 return Util.getAbsolutePath(project.getOutputLocation());347 return BuilderUtil.getAbsolutePath(project.getOutputLocation()); 353 348 } 354 349 catch(JavaModelException e) trunk/descent.building/src/descent/internal/building/debuild/RecursiveDependancyCollector.java
r1174 r1175 23 23 import descent.core.IParent; 24 24 import descent.core.JavaModelException; 25 import descent.internal.building.BuilderUtil; 25 26 /** 26 27 * Class that can recurse through dependancies to generate a list of all files … … 145 146 { 146 147 return new ObjectFile(project, 147 new File( Util.getAbsolutePath(cu.getPath())),148 new File(BuilderUtil.getAbsolutePath(cu.getPath())), 148 149 cu.getFullyQualifiedName(), 149 150 isLibraryFile); trunk/descent.building/src/descent/internal/building/ui/AbstractBuilderTab.java
r1174 r1175 6 6 import org.eclipse.core.resources.IWorkspaceRoot; 7 7 import org.eclipse.core.resources.ResourcesPlugin; 8 import org.eclipse.core.runtime.CoreException; 8 9 import org.eclipse.debug.core.ILaunchConfiguration; 9 10 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; … … 13 14 import org.eclipse.jface.resource.JFaceResources; 14 15 import org.eclipse.swt.SWT; 16 import org.eclipse.swt.events.ModifyEvent; 17 import org.eclipse.swt.events.ModifyListener; 18 import org.eclipse.swt.events.SelectionAdapter; 19 import org.eclipse.swt.events.SelectionEvent; 20 import org.eclipse.swt.events.SelectionListener; 15 21 import org.eclipse.swt.graphics.Image; 16 22 import org.eclipse.swt.layout.GridData; … … 21 27 import org.eclipse.swt.widgets.Label; 22 28 import org.eclipse.swt.widgets.Layout; 29 import org.eclipse.swt.widgets.Text; 23 30 import org.eclipse.ui.IEditorInput; 24 31 import org.eclipse.ui.IEditorPart; … … 35 42 import descent.internal.ui.util.PixelConverter; 36 43 37 // TODO comments 38 public abstract class AbstractBuilderTab extends AbstractLaunchConfigurationTab 44 /** 45 * Defines a shared implementation for all the builder tabs used in the Descent 46 * builder configuration. In addition to a number of useful convience methods, 47 * this provides a setting interface which implementations can use to encapsulate 48 * the various settings they provide. See {@link descent.internal.building.ui.AbstractBuilderTab.ISetting} 49 * for more information. 50 * 51 * @author Robert Fraser 52 */ 53 /* package */ abstract class AbstractBuilderTab extends AbstractLaunchConfigurationTab 39 54 { 40 55 //-------------------------------------------------------------------------- 41 56 // Setting interface 42 57 43 protected interface ISetting 44 { 58 /** 59 * A setting is a way to encapsulate controls and UI logic related to a 60 * one or more attributes. Since a single tab page usually consists of many 61 * different settings that rarely interact, this is an way to avoid namespace 62 * clashes and ensure updates are applied throughout. An AbstractBuilderTab 63 * consists of one or more of these, set by the getSettings() method. 64 */ 65 protected static interface ISetting 66 { 67 /** 68 * Adds the settings to the control. Settings will be added in the order 69 * of the array returned by the getSettings() method. 70 * 71 * @param comp the tab to add the controls to 72 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(org.eclipse.swt.widgets.Composite) 73 */ 45 74 public void addToControl(Composite comp); 75 76 /** 77 * Initialize the launch configuration with information about this setting. 78 * 79 * @param config the launch config to initialize. 80 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration) 81 */ 46 82 public void initializeFrom(ILaunchConfiguration config); 83 84 /** 85 * Applies the setting to the given launch configuration. 86 * 87 * @param config the config to apply the setting to 88 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy) 89 */ 47 90 public void performApply(ILaunchConfigurationWorkingCopy config); 91 92 /** 93 * Sets the default values in the configuration. 94 * 95 * @param config 96 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy) 97 */ 48 98 public void setDefaults(ILaunchConfigurationWorkingCopy config); 99 100 /** 101 * Checks whether the setting is valid. If the setting is not valid, this 102 * should set the error message on the page. 103 */ 49 104 public void validate(); 50 105 } … … 67 122 private Group fGroup; 68 123 124 /** 125 * Creates a new group setting with the given parameters 126 * 127 * @param label the label to apply to the group 128 * @param width the width (number of columns) the group should 129 * take up on the top GridLayout. 130 * @param numColumns the number of columns the resulting group should 131 * have. 132 * @param subSettings the settings within the group 133 */ 69 134 public GroupSetting(String label, int width, int numColumns, 70 135 ISetting[] subSettings) … … 110 175 return; 111 176 } 177 } 178 } 179 180 //-------------------------------------------------------------------------- 181 // Text setting 182 183 /** 184 * A setting that consists of a text field, optionally with a browse button. 185 */ 186 protected abstract class TextSetting implements ISetting 187 { 188 private final String fAttribute; 189 private final String fLabelString; 190 private final int fNumColumns; 191 private final boolean fBrowseButton; 192 private final boolean fEditable; 193 194 protected Label fLabel; 195 protected Text fText; 196 protected Button fButton; 197 198 /** 199 * Creates a new text setting with the given parameters. 200 * 201 * @param attribute the attribute the text setting refers to 202 * @param label the text of the label 203 * @param numColumns the number of columns the three controls should 204 * take up. Must be >= 2 if no browse button and 205 * >= 3 if there is a browse button 206 * @param browseButton should there be a browse button? if this is true, 207 * numColumns must be >= 3 and {@link #browse()} must 208 * be implemented in the subclass. 209 * @param editable sets whether or not the text field is editable. 210 * This should only be false if browseButton is true, 211 * for obvious reasons. 212 */ 213 protected TextSetting(String attribute, String label, int numColumns, 214 boolean browseButton, boolean editable) 215 { 216 fAttribute = attribute; 217 fLabelString = label; 218 fNumColumns = numColumns; 219 fBrowseButton = browseButton; 220 fEditable = editable; 221 } 222 223 public final void addToControl(Composite comp) 224 { 225 fLabel = new Label(comp, SWT.NONE); 226 fLabel.setText(fLabelString); 227 GridData gd = new GridData(); 228 gd.horizontalSpan = 1; 229 fLabel.setLayoutData(gd); 230 231 fText = new Text(comp, SWT.SINGLE | SWT.BORDER); 232 gd = new GridData(GridData.FILL_HORIZONTAL); 233 gd.horizontalSpan = fNumColumns - (fBrowseButton ? 2 : 1); 234 fText.setLayoutData(gd); 235 fText.setEditable(fEditable); 236 fText.addModifyListener(new ModifyListener() 237 { 238 public void modifyText(ModifyEvent evt) 239 { 240 validatePage(); 241 updateLaunchConfigurationDialog(); 242 } 243 }); 244 245 if(fBrowseButton) 246 { 247 fButton = new Button(comp, SWT.PUSH); 248 fButton.setText("Browse..."); 249 gd = new GridData(); 250 gd.horizontalSpan = 1; 251 fButton.setLayoutData(gd); 252 setButtonDimensionHint(fButton); 253 fButton.addSelectionListener(new SelectionAdapter() 254 { 255 public void widgetSelected(SelectionEvent evt) 256 { 257 String text = browse(); 258 if(null != text) 259 fText.setText(text); 260 } 261 }); 262 } 263 } 264 265 /** 266 * The function to call when the browse button is selected. If 267 * browseButton is true, this must be specified. 268 * 269 * @return the new text to place in the field 270 */ 271 protected String browse() 272 { 273 throw new UnsupportedOperationException(); 274 } 275 276 public final void initializeFrom(ILaunchConfiguration config) 277 { 278 String value = ""; 279 try 280 { 281 value = config.getAttribute(fAttribute, ""); 282 } 283 catch(CoreException e) { } 284 285 fText.setText(value); 286 } 287 288 public final void performApply(ILaunchConfigurationWorkingCopy config) 289 { 290 config.setAttribute(fAttribute, fText.getText().trim()); 112 291 } 113 292 } … … 343 522 * @param numColumns the number of columns it should take up 344 523 */ 345 protected Label createSpacer(Composite parent, int numColumns)524 protected static Label createSpacer(Composite parent, int numColumns) 346 525 { 347 526 Label spacer = new Label(parent, SWT.NONE); … … 358 537 } 359 538 539 protected Button createRadioButton(Composite parent, int numColumns, 540 String label, int indent, SelectionListener listener) 541 { 542 final Button button = new Button(parent, SWT.RADIO); 543 button.setText(label); 544 GridData gd = new GridData(); 545 gd.horizontalSpan = numColumns; 546 gd.horizontalIndent = indent; 547 button.setLayoutData(gd); 548 549 if(null == listener) 550 listener = new SelectionAdapter() 551 { 552 public void widgetSelected(SelectionEvent e) 553 { 554 if(button.getSelection()) 555 updateLaunchConfigurationDialog(); 556 } 557 }; 558 button.addSelectionListener(listener); 559 560 return button; 561 } 562 360 563 /** 361 564 * Convenience method to get access to the java model. trunk/descent.building/src/descent/internal/building/ui/CompilerTab.java
r1174 r1175 10 10 import org.eclipse.swt.events.ModifyEvent; 11 11 import org.eclipse.swt.events.ModifyListener; 12 import org.eclipse.swt.events.SelectionAdapter; 13 import org.eclipse.swt.events.SelectionEvent; 12 14 import org.eclipse.swt.layout.GridData; 13 15 import org.eclipse.swt.layout.GridLayout; … … 17 19 import org.eclipse.swt.widgets.Layout; 18 20 import org.eclipse.swt.widgets.Link; 21 import org.eclipse.ui.dialogs.PreferencesUtil; 19 22 20 23 import descent.building.IDescentBuilderConstants; … … 23 26 import descent.launching.JavaRuntime; 24 27 25 publicclass CompilerTab extends AbstractBuilderTab28 /* package */ final class CompilerTab extends AbstractBuilderTab 26 29 { 27 30 //-------------------------------------------------------------------------- … … 47 50 gd.horizontalSpan = 1; 48 51 fHelpText.setLayoutData(gd); 52 fHelpText.addSelectionListener(new SelectionAdapter() 53 { 54 public void widgetSelected(SelectionEvent e) 55 { 56 PreferencesUtil.createPreferenceDialogOn(getShell(), 57 "descent.debug.ui.preferences.VMPreferencePage", 58 null, null).open(); 59 60 // Reset stuff so new changes are reflected in this dialog 61 reinitializeCompilers(); 62 int selectionIndex = fCombo.getSelectionIndex(); 63 resetComboItems(); 64 fCombo.select(fCombo.getSelectionIndex() >= fCompilers.length ? 65 0 : selectionIndex); 66 } 67 }); 49 68 50 69 createSpacer(fGroup, 1); … … 62 81 fCompilers[selectedIndex] : null; 63 82 compilerOptions.compilerModeChanged(selectedCompiler); 83 84 validatePage(); 85 updateLaunchConfigurationDialog(); 64 86 } 65 87 }); 66 88 67 89 initializeCompilers(); 68 String[] items = new String[fCompilers.length]; 69 for(int i = 0; i < items.length; i++) 70 items[i] = getCompilerLabel(fCompilers[i]); 71 fCombo.setItems(items); 72 } 73 90 resetComboItems(); 91 } 92 93 /** 94 * Initialize compilers if they haven't been initialized (since I'm not 95 * sure which order createControl and setDefaults will be set in) 96 */ 74 97 private void initializeCompilers() 75 98 { … … 77 100 return; 78 101 102 reinitializeCompilers(); 103 } 104 105 /** 106 * Reset the compiler list whether it's already been set or not 107 */ 108 private void reinitializeCompilers() 109 { 79 110 List<IVMInstall> compilers = new ArrayList<IVMInstall>(); 80 111 for(IVMInstallType vmInstallType : JavaRuntime.getVMInstallTypes()) … … 82 113 compilers.add(vmInstall); 83 114 fCompilers = compilers.toArray(new IVMInstall[compilers.size()]); 115 } 116 117 private void resetComboItems() 118 { 119 String[] items = new String[fCompilers.length]; 120 for(int i = 0; i < items.length; i++) 121 items[i] = getCompilerLabel(fCompilers[i]); 122 fCombo.setItems(items); 84 123 } 85 124 … … 106 145 try 107 146 { 108 compiler TypeId = config.getAttribute(IDescentBuilderConstants.ATTR_COMPILER_ID, "");147 compilerId = config.getAttribute(IDescentBuilderConstants.ATTR_COMPILER_ID, ""); 109 148 } 110 149 catch(CoreException e) { } trunk/descent.building/src/descent/internal/building/ui/DebuildTabGroup.java
r1174 r1175 12 12 ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] 13 13 { 14 new BuildTab(),14 new GeneralTab(), 15 15 new CompilerTab(), 16 16 new EnvironmentTab(), trunk/descent.building/src/descent/internal/building/ui/GeneralTab.java
r1174 r1175 9 9 import org.eclipse.core.runtime.IPath; 10 10 import org.eclipse.core.runtime.IStatus; 11 import org.eclipse.core.runtime.Path; 11 12 import org.eclipse.debug.core.ILaunchConfiguration; 12 13 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; … … 14 15 import org.eclipse.jface.window.Window; 15 16 import org.eclipse.swt.SWT; 16 import org.eclipse.swt.events.ModifyEvent;17 import org.eclipse.swt.events.ModifyListener;18 17 import org.eclipse.swt.events.SelectionAdapter; 19 18 import org.eclipse.swt.events.SelectionEvent; … … 22 21 import org.eclipse.swt.widgets.Button; 23 22 import org.eclipse.swt.widgets.Composite; 23 import org.eclipse.swt.widgets.FileDialog; 24 import org.eclipse.swt.widgets.Group; 24 25 import org.eclipse.swt.widgets.Label; 25 26 import org.eclipse.swt.widgets.Layout; 26 import org.eclipse.swt.widgets.Text;27 27 import org.eclipse.ui.dialogs.ElementListSelectionDialog; 28 28 29 import descent.building.IDescentBuilderConstants;30 29 import descent.core.IJavaProject; 31 30 import descent.core.JavaCore; 32 31 import descent.core.JavaModelException; 32 import descent.internal.building.BuilderUtil; 33 33 import descent.internal.building.BuildingPlugin; 34 34 import descent.internal.ui.wizards.dialogfields.DialogField; … … 39 39 import descent.ui.JavaElementSorter; 40 40 41 import static descent.building.IDescentBuilderConstants.*; 42 41 43 @SuppressWarnings("unchecked") 42 public class BuildTab extends AbstractBuilderTab43 { 44 /* package */ final class GeneralTab extends AbstractBuilderTab 45 { 44 46 //-------------------------------------------------------------------------- 45 47 // Project selection 46 48 47 private final class ProjectSetting implements ISetting 48 { 49 private Label fLabel; 50 private Text fText; 51 private Button fButton; 52 53 public void addToControl(Composite comp) 54 { 55 fLabel = new Label(comp, SWT.NONE); 56 fLabel.setText("Project:"); 57 GridData gd = new GridData(); 58 fLabel.setLayoutData(gd); 59 60 fText = new Text(comp, SWT.SINGLE | SWT.BORDER); 61 fText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); 62 fText.addModifyListener(new ModifyListener() 63 { 64 public void modifyText(ModifyEvent evt) 65 { 66 validatePage(); 67 updateLaunchConfigurationDialog(); 68 } 69 }); 70 71 fButton = new Button(comp, SWT.PUSH); 72 fButton.setText("Browse..."); 73 gd = new GridData(); 74 fButton.setLayoutData(gd); 75 setButtonDimensionHint(fButton); 76 fButton.addSelectionListener(new SelectionAdapter() 77 { 78 public void widgetSelected(SelectionEvent evt) 79 { 80 handleProjectButtonSelected(); 81 } 82 }); 49 private final class ProjectSetting extends TextSetting 50 { 51 ProjectSetting() 52 { 53 super(ATTR_PROJECT_NAME, "Project:", 3, true, false); 83 54 } 84 55 … … 87 58 * context for choosing the container that should be run. 88 59 */ 89 private void handleProjectButtonSelected() 60 @Override 61 protected String browse() 90 62 { 91 63 IJavaProject project = chooseJavaProject(); 92 if (project == null) 93 { 94 return; 95 } 96 97 String projectName = project.getElementName(); 98 fText.setText(projectName); 64 if(null != project) 65 { 66 String name = project.getElementName(); 67 if(!name.equals(fText.getText())) 68 outputFileSetting.projectChanged(project); 69 return name; 70 } 71 else 72 { 73 return null; 74 } 99 75 } 100 76 … … 149 125 } 150 126 151 public void initializeFrom(ILaunchConfiguration config)152 {153 String projectName = "";154 try155 {156 projectName = config.getAttribute(IDescentBuilderConstants.ATTR_PROJECT_NAME, "");157 }158 catch(CoreException e) { }159 160 fText.setText(projectName);161 }162 163 public void performApply(ILaunchConfigurationWorkingCopy config)164 {165 config.setAttribute(IDescentBuilderConstants.ATTR_PROJECT_NAME, fText.getText().trim());166 }167 168 127 public void setDefaults(ILaunchConfigurationWorkingCopy config) 169 128 { … … 174 133 projectName = javaProject.getElementName(); 175 134 176 config.setAttribute( IDescentBuilderConstants.ATTR_PROJECT_NAME, projectName);135 config.setAttribute(ATTR_PROJECT_NAME, projectName); 177 136 178 137 // Also, rename the config here (don't do it anywhere else in the … … 221 180 222 181 //-------------------------------------------------------------------------- 182 // Output type 183 184 private final class OutputTypeSetting implements ISetting 185 { 186 private Label fLabel; 187 private Button fExecutableRadio; 188 private Button fStaticLibRadio; 189 190 public void addToControl(Composite comp) 191 { 192 fLabel = new Label(comp, SWT.LEFT); 193 fLabel.setText("Target type:"); 194 GridData gd = new GridData(); 195 gd.horizontalSpan = 3; 196 fLabel.setLayoutData(gd); 197 198 fExecutableRadio = createRadioButton(comp, 3, "Executable", 25, 199 new SelectionAdapter() 200 { 201 public void widgetSelected(SelectionEvent e) 202 { 203 if(fExecutableRadio.getSelection()) 204 { 205 outputFileSetting.outputTypeChanged(); 206 updateLaunchConfigurationDialog(); 207 } 208 } 209 }); 210 fStaticLibRadio = createRadioButton(comp, 3, "Static library", 25, 211 new SelectionAdapter() 212 { 213 public void widgetSelected(SelectionEvent e) 214 { 215 if(fStaticLibRadio.getSelection()) 216 { 217 outputFileSetting.outputTypeChanged(); 218 updateLaunchConfigurationDialog(); 219 } 220 } 221 }); 222 createSpacer(comp, 3); 223 } 224 225 public void initializeFrom(ILaunchConfiguration config) 226 { 227 String outputType = OUTPUT_TYPE_EXECUTABLE; 228 try 229 { 230 outputType = config.getAttribute(ATTR_OUTPUT_TYPE, OUTPUT_TYPE_EXECUTABLE); 231 } 232 catch(CoreException e) { } 233 234 if(outputType.equals(OUTPUT_TYPE_EXECUTABLE)) 235 { 236 fExecutableRadio.setSelection(true); 237 fStaticLibRadio.setSelection(false); 238 } 239 else if(outputType.equals(OUTPUT_TYPE_STATIC_LIBRARY)) 240 { 241 fExecutableRadio.setSelection(false); 242 fStaticLibRadio.setSelection(true); 243 } 244 else 245 { 246 // Set the defaults 247 fExecutableRadio.setSelection(true); 248 fStaticLibRadio.setSelection(false); 249 } 250 } 251 252 public void performApply(ILaunchConfigurationWorkingCopy config) 253 { 254 if(fExecutableRadio.getSelection()) 255 config.setAttribute(ATTR_OUTPUT_TYPE, OUTPUT_TYPE_EXECUTABLE); 256 else 257 config.setAttribute(ATTR_OUTPUT_TYPE, OUTPUT_TYPE_STATIC_LIBRARY); 258 } 259 260 public void setDefaults(ILaunchConfigurationWorkingCopy config) 261 { 262 config.setAttribute(ATTR_OUTPUT_TYPE, OUTPUT_TYPE_EXECUTABLE); 263 } 264 265 public void validate() 266 { 267 // Nothing to do -- any choice is valid 268 } 269 270 public String getExtension() 271 { 272 if(fExecutableRadio == null) 273 return BuilderUtil.EXTENSION_EXECUTABLE; 274 275 if(fExecutableRadio.getSelection()) 276 return BuilderUtil.EXTENSION_EXECUTABLE; 277 else 278 return BuilderUtil.EXTENSION_STATIC_LIBRARY; 279 } 280 } 281 282 //-------------------------------------------------------------------------- 283 // Output file 284 285 private final class OutputFileSetting extends TextSetting 286 { 287 OutputFileSetting() 288 { 289 super(ATTR_OUTPUT_FILE, "Output file:", 3, true, true); 290 } 291 292 @Override 293 protected String browse() 294 { 295 String defaultExtension = getExtension(); 296 String defaultLocation = fText.getText(); 297 if(0 == defaultLocation.length()) 298 defaultLocation = null; 299 300 FileDialog dialog = new FileDialog(getShell(), SWT.SAVE); 301 dialog.setText("Output file location"); 302 dialog.setFilterExtensions((defaultExtension.length()) > 0 ? 303 new String[] { "*" + getExtension(), "*.*" } : 304 new String[] { "*.*" }); 305 dialog.setFilterPath(toFilterPath(defaultLocation)); 306 307 return normalizeFilename(dialog.open()); 308 } 309 310 private String toFilterPath(String filename) 311 { 312 IPath path = new Path(filename); 313 if(path.segmentCount() <= 1) 314 return null; 315 return path.removeLastSegments(1).removeTrailingSeparator().toOSString(); 316 } 317 318 private String normalizeFilename(String filename) 319 { 320 return new Path(filename).toString(); 321 } 322 323 public void setDefaults(ILaunchConfigurationWorkingCopy config) 324 { 325 config.setAttribute(ATTR_OUTPUT_FILE, 326 getDefaultLocationForProject(getActiveProject())); 327 } 328 329 public void validate() 330 { 331 String pathText = fText.getText().trim(); 332 if (pathText.length() == 0) 333 { 334 setErrorMessage("Output path not defined"); 335 return; 336 } 337 338 // No way to check if a file is a valid filename since that's 339 // file-system (NTFS/FAT/whatever) dependent :-(. I guess some small 340 // sanity checks could be added... but whatever, I'll just handle 341 // the error in the builder itself 342 } 343 344 public void projectChanged(IJavaProject project) 345 { 346 if(null != fText) 347 fText.setText(getDefaultLocationForProject(project)); 348 } 349 350 public void outputTypeChanged() 351 { 352 if(null != fText) 353 fText.setText(updateExtension(fText.getText())); 354 } 355 356 /** 357 * Gets the path for the default output file in the given project. 358 * 359 * @param project the project whose output folder the result should be in 360 * @return the string representation of the output path 361 */ 362 private String getDefaultLocationForProject(IJavaProject project) 363 { 364 if(null == project || !project.exists()) 365 return ""; 366 367 try 368 { 369 StringBuilder outputFile = new StringBuilder(); 370 outputFile.append(BuilderUtil.getAbsolutePath(project. 371 getOutputLocation().makeAbsolute())); 372 outputFile.append(IPath.SEPARATOR); 373 outputFile.append(project.getElementName()); 374 return updateExtension(outputFile.toString()); 375 } 376 catch(JavaModelException e) 377 { 378 return ""; 379 } 380 } 381 382 /** 383 * Updates the extension in the given path to reflect the extension that 384 * should be there depending on the file type. For example if the given 385 * path is "C:\d\project\out.exe" and the type is changed to 386 * dynamic library, this method will return "C:\d\project\out.dll". 387 * 388 * @param filename 389 * @return 390 */ 391 private String updateExtension(String filename) 392 { 393 // PERHAPS on unix systems should this actually return libXYZ.a for an 394 // input of XYZ if the type is static library...? 395 396 if(null == filename || 0 == filename.length()) 397
