Changeset 1177
- Timestamp:
- 05/26/08 12:07:47 (8 months ago)
- Files:
-
- trunk/descent.building/icons/full/obj16/checked.png (added)
- trunk/descent.building/icons/full/obj16/unchecked.png (added)
- trunk/descent.building/src/descent/building/compiler/BooleanOption.java (added)
- trunk/descent.building/src/descent/building/compiler/CompilerOption.java (added)
- trunk/descent.building/src/descent/building/compiler/EnumOption.java (added)
- trunk/descent.building/src/descent/building/compiler/ICompilerInterface.java (modified) (1 diff)
- trunk/descent.building/src/descent/building/compiler/StringOption.java (added)
- trunk/descent.building/src/descent/internal/building/compiler/DmdCompilerInterface.java (modified) (3 diffs)
- trunk/descent.building/src/descent/internal/building/ui/AbstractBuilderTab.java (modified) (7 diffs)
- trunk/descent.building/src/descent/internal/building/ui/CompilerTab.java (modified) (11 diffs)
- trunk/descent.building/src/descent/internal/building/ui/GeneralTab.java (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/descent.building/src/descent/building/compiler/ICompilerInterface.java
r1174 r1177 36 36 */ 37 37 public IResponseInterpreter createLinkResponseInterpreter(); 38 39 /** 40 * Gets the compiler options which should be presented in the UI. 41 * 42 * @return the ordered list of compiler options to be presented in the UI. 43 */ 44 // TODO comment about what sorts of options should be included etc 45 public CompilerOption[] getOptions(); 38 46 } trunk/descent.building/src/descent/internal/building/compiler/DmdCompilerInterface.java
r1174 r1177 6 6 import descent.building.compiler.AbstractCompileCommand; 7 7 import descent.building.compiler.AbstractLinkCommand; 8 import descent.building.compiler.BooleanOption; 9 import descent.building.compiler.CompilerOption; 8 10 import descent.building.compiler.ICompileCommand; 9 11 import descent.building.compiler.ICompilerInterface; … … 252 254 253 255 //-------------------------------------------------------------------------- 256 // UI Options 257 258 private static final CompilerOption[] uiOptions; 259 260 static 261 { 262 final String GROUP_FEATURES; 263 264 uiOptions = new CompilerOption[] 265 { 266 //------------------------------------------------------------------ 267 // Features 268 269 }; 270 } 271 272 //-------------------------------------------------------------------------- 254 273 // Interface implementation 255 274 … … 285 304 return new DmdResponseInterpreter(); 286 305 } 306 307 public CompilerOption[] getOptions() 308 { 309 // TODO Auto-generated method stub 310 return uiOptions; 311 } 287 312 } trunk/descent.building/src/descent/internal/building/ui/AbstractBuilderTab.java
r1175 r1177 100 100 /** 101 101 * Checks whether the setting is valid. If the setting is not valid, this 102 * should set the error message on the page.103 */ 104 public voidvalidate();102 * should return the error message to be displayed to the user. 103 */ 104 public String validate(); 105 105 } 106 106 … … 167 167 } 168 168 169 public voidvalidate()169 public String validate() 170 170 { 171 171 for(ISetting setting : fChildren) 172 172 { 173 setting.validate();174 if(null != getErrorMessage())175 return ;173 String message = setting.validate(); 174 if(null != message) 175 return message; 176 176 } 177 return null; 177 178 } 178 179 } … … 331 332 for(ISetting setting : settings) 332 333 { 333 setting.validate(); 334 if(null != getErrorMessage()) 334 String message = setting.validate(); 335 if(null != message) 336 { 337 setErrorMessage(message); 335 338 return; 339 } 336 340 } 337 341 } … … 358 362 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy) 359 363 */ 360 public void setDefaults(ILaunchConfigurationWorkingCopy config)364 public final void setDefaults(ILaunchConfigurationWorkingCopy config) 361 365 { 362 366 for(ISetting setting : settings) … … 395 399 } 396 400 397 pr ivatestatic Image createImage(String path)401 protected static Image createImage(String path) 398 402 { 399 403 return BuildingPlugin.getImageDescriptor(path).createImage(); … … 401 405 402 406 @Override 403 public Image getImage()407 public final Image getImage() 404 408 { 405 409 return fTabIcon; … … 414 418 * internalized by the JVM). 415 419 */ 416 protected final List EMPTY_LIST = new ArrayList(0); 420 protected static final List EMPTY_LIST = new ArrayList(0); 421 422 /** 423 * An empty array object to be used by content providers for elements 424 * that are barren and childless. 425 */ 426 protected static final Object[] EMPTY_ARRAY = new Object[] {}; 417 427 418 428 /** trunk/descent.building/src/descent/internal/building/ui/CompilerTab.java
r1175 r1177 3 3 import java.util.ArrayList; 4 4 import java.util.List; 5 import java.util.Map; 6 import java.util.TreeMap; 5 7 6 8 import org.eclipse.core.runtime.CoreException; 7 9 import org.eclipse.debug.core.ILaunchConfiguration; 8 10 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; 11 import org.eclipse.jface.viewers.CellEditor; 12 import org.eclipse.jface.viewers.CheckboxCellEditor; 13 import org.eclipse.jface.viewers.ColumnLabelProvider; 14 import org.eclipse.jface.viewers.ColumnViewerEditor; 15 import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy; 16 import org.eclipse.jface.viewers.ComboBoxCellEditor; 17 import org.eclipse.jface.viewers.EditingSupport; 18 import org.eclipse.jface.viewers.ITreeContentProvider; 19 import org.eclipse.jface.viewers.TextCellEditor; 20 import org.eclipse.jface.viewers.TreeViewer; 21 import org.eclipse.jface.viewers.TreeViewerColumn; 22 import org.eclipse.jface.viewers.TreeViewerEditor; 23 import org.eclipse.jface.viewers.Viewer; 9 24 import org.eclipse.swt.SWT; 10 25 import org.eclipse.swt.events.ModifyEvent; … … 12 27 import org.eclipse.swt.events.SelectionAdapter; 13 28 import org.eclipse.swt.events.SelectionEvent; 29 import org.eclipse.swt.graphics.Image; 14 30 import org.eclipse.swt.layout.GridData; 15 31 import org.eclipse.swt.layout.GridLayout; 16 32 import org.eclipse.swt.widgets.Combo; 17 33 import org.eclipse.swt.widgets.Composite; 18 import org.eclipse.swt.widgets.Group;19 34 import org.eclipse.swt.widgets.Layout; 20 35 import org.eclipse.swt.widgets.Link; … … 22 37 23 38 import descent.building.IDescentBuilderConstants; 39 import descent.building.compiler.BooleanOption; 40 import descent.building.compiler.CompilerOption; 41 import descent.building.compiler.EnumOption; 42 import descent.building.compiler.ICompilerInterface; 43 import descent.building.compiler.StringOption; 44 import descent.internal.building.compiler.DmdCompilerInterface; 24 45 import descent.launching.IVMInstall; 25 46 import descent.launching.IVMInstallType; … … 27 48 28 49 /* package */ final class CompilerTab extends AbstractBuilderTab 29 { 50 { 30 51 //-------------------------------------------------------------------------- 31 52 // Compiler selection … … 33 54 private final class CompilerSetting implements ISetting 34 55 { 35 private Group fGroup;36 56 private Link fHelpText; 37 57 private Combo fCombo; … … 40 60 public void addToControl(Composite comp) 41 61 { 42 fGroup = createGroup(comp, "Compiler Selection", 1, 1); 43 44 fHelpText = new Link(fGroup, SWT.LEFT | SWT.WRAP); 62 // Create a sub-composite so the table viewer doesn't take over the 63 // entire tab 64 comp = new Composite(comp, SWT.NONE); 65 GridData gd = new GridData(GridData.FILL_HORIZONTAL); 66 gd.horizontalSpan = 1; 67 comp.setLayoutData(gd); 68 GridLayout layout = new GridLayout(); 69 layout.numColumns = 1; 70 comp.setLayout(layout); 71 72 fHelpText = new Link(comp, SWT.LEFT | SWT.WRAP); 45 73 fHelpText.setText("Select the compiler/standard library set to use " + 46 "for this build configuration. Use the <a>Compilers " +47 "preference page</a> to set up compiler/standard library " +48 "configurations.");49 GridDatagd = new GridData(GridData.FILL_BOTH);74 "for this build configuration. Use the <a>Compilers " + 75 "preference page</a> to set up compiler/standard library " + 76 "configurations."); 77 gd = new GridData(GridData.FILL_BOTH); 50 78 gd.horizontalSpan = 1; 51 79 fHelpText.setLayoutData(gd); … … 67 95 }); 68 96 69 createSpacer(fGroup, 1); 70 71 fCombo = new Combo(fGroup, SWT.DROP_DOWN | SWT.READ_ONLY); 97 fCombo = new Combo(comp, SWT.DROP_DOWN | SWT.READ_ONLY); 72 98 gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); 73 99 gd.horizontalSpan = 1; … … 196 222 } 197 223 198 public voidvalidate()224 public String validate() 199 225 { 200 226 int selectedIndex = fCombo.getSelectionIndex(); 201 227 if(selectedIndex < 0) 202 { 203 setErrorMessage("You must select a compiler to use"); 204 return; 205 } 228 return "You must select a compiler to use"; 229 230 return null; 206 231 } 207 232 } … … 209 234 public class CompilerOptions implements ISetting 210 235 { 211 private Group fGroup; 236 private abstract class CompilerUIOption 237 { 238 public TreeEntry parent; 239 240 public abstract CompilerOption getOption(); 241 public abstract CellEditor getCellEditor(); 242 public abstract Object getValue(); 243 public abstract void setValue(Object value); 244 public abstract String getText(); 245 } 246 247 private final class CheckboxUIOption extends CompilerUIOption 248 { 249 private BooleanOption option; 250 public Boolean selected = Boolean.FALSE; 251 private CheckboxCellEditor editor; 252 253 public CheckboxUIOption(BooleanOption option) 254 { 255 this.option = option; 256 } 257 258 @Override 259 public CompilerOption getOption() 260 { 261 return option; 262 } 263 264 @Override 265 public CellEditor getCellEditor() 266 { 267 if(null == editor) 268 editor = new CheckboxCellEditor(fViewer.getTree()); 269 270 return editor; 271 } 272 273 @Override 274 public Object getValue() 275 { 276 return selected; 277 } 278 279 @Override 280 public void setValue(Object value) 281 { 282 selected = (Boolean) value; 283 } 284 285 @Override 286 public String getText() 287 { 288 return selected ? option.getOnText() : option.getOffText(); 289 } 290 } 291 292 private final class ComboUIOption extends CompilerUIOption 293 { 294 private EnumOption option; 295 public Integer selected = Integer.valueOf(0); 296 private ComboBoxCellEditor editor; 297 298 public ComboUIOption(EnumOption option) 299 { 300 this.option = option; 301 } 302 303 @Override 304 public CompilerOption getOption() 305 { 306 return option; 307 } 308 309 @Override 310 public CellEditor getCellEditor() 311 { 312 if(null == editor) 313 { 314 editor = new ComboBoxCellEditor(fViewer.getTree(), 315 option.getOptionEditLabels()); 316 } 317 318 return editor; 319 } 320 321 @Override 322 public Object getValue() 323 { 324 return selected; 325 } 326 327 @Override 328 public void setValue(Object value) 329 { 330 selected = (Integer) value; 331 } 332 333 @Override 334 public String getText() 335 { 336 return option.getOptionViewLabels()[selected]; 337 } 338 } 339 340 private final class TextUIOption extends CompilerUIOption 341 { 342 private StringOption option; 343 public String selected = ""; 344 private TextCellEditor editor; 345 346 public TextUIOption(StringOption option) 347 { 348 this.option = option; 349 } 350 351 @Override 352 public CompilerOption getOption() 353 { 354 return option; 355 } 356 357 @Override 358 public CellEditor getCellEditor() 359 { 360 if(null == editor) 361 editor = new TextCellEditor(fViewer.getTree()); 362 363 return editor; 364 } 365 366 @Override 367 public String getText() 368 { 369 return selected; 370 } 371 372 @Override 373 public Object getValue() 374 { 375 return selected; 376 } 377 378 @Override 379 public void setValue(Object value) 380 { 381 selected = (String) value; 382 } 383 } 384 385 private final class TreeEntry 386 { 387 private final String label; 388 private final CompilerUIOption[] children; 389 390 public TreeEntry(String label, CompilerUIOption[] children) 391 { 392 this.label = label; 393 this.children = children; 394 395 for(CompilerUIOption child : children) 396 child.parent = this; 397 } 398 } 399 400 private final class OptionsContentProvider implements ITreeContentProvider 401 { 402 public Object[] getChildren(Object parentElement) 403 { 404 if(!(parentElement instanceof TreeEntry)) 405 return EMPTY_ARRAY; 406 return ((TreeEntry) parentElement).children; 407 } 408 409 public Object getParent(Object element) 410 { 411 if(!(element instanceof CompilerUIOption)) 412 return null; 413 return ((CompilerUIOption) element).parent; 414 } 415 416 public boolean hasChildren(Object element) 417 { 418 // Assume every tree entry has at least one element; if it 419 // doesn't, the plus to expand it will just disappear when 420 // the user clicks on it 421 return element instanceof TreeEntry; 422 } 423 424 public Object[] getElements(Object inputElement) 425 { 426 return fEntries; 427 } 428 429 public void dispose() 430 { 431 // Nothing to do 432 } 433 434 public void inputChanged(Viewer viewer, Object oldInput, 435 Object newInput) 436 { 437 // TODO 438 } 439 } 440 212 441 private IVMInstall fSelectedCompiler; 442 private TreeViewer fViewer; 443 private TreeEntry[] fEntries; 213 444 214 445 public void addToControl(Composite comp) 215 446 { 216 fGroup = createGroup(comp, "Compiler Options", 1, 1); 217 218 createSpacer(fGroup, 1); 219 220 // TODO make the list 447 fEntries = getTree(); 448 449 fViewer = new TreeViewer(comp, SWT.BORDER | SWT.FULL_SELECTION); 450 fViewer.getTree().setHeaderVisible(true); 451 fViewer.getTree().setLinesVisible(true); 452 TreeViewerEditor.create(fViewer, 453 // Here comes the world's most unnecessarily long class name... 454 new ColumnViewerEditorActivationStrategy(fViewer), 455 ColumnViewerEditor.DEFAULT); 456 457 TreeViewerColumn column = new TreeViewerColumn(fViewer, SWT.NONE); 458 column.getColumn().setWidth(200); 459 column.getColumn().setText("Option"); 460 column.setLabelProvider(new ColumnLabelProvider() 461 { 462 @Override 463 public String getText(Object element) 464 { 465 if(element instanceof TreeEntry) 466 return ((TreeEntry) element).label; 467 else 468 return ((CompilerUIOption) element).getOption().getLabel(); 469 } 470 }); 471 472 column = new TreeViewerColumn(fViewer, SWT.NONE); 473 column.getColumn().setWidth(200); 474 column.getColumn().setText("Value"); 475 column.setLabelProvider(new ColumnLabelProvider() 476 { 477 @Override 478 public Image getImage(Object element) 479 { 480 if(element instanceof CheckboxUIOption) 481 return ((CheckboxUIOption) element).selected ? 482 fCheckedIcon : fUncheckedIcon; 483 else 484 return null; 485 } 486 487 @Override 488 public String getText(Object element) 489 { 490 if(element instanceof CompilerUIOption) 491 return ((CompilerUIOption) element).getText(); 492 else 493 return ""; 494 } 495 }); 496 column.setEditingSupport(new EditingSupport(fViewer) 497 { 498 @Override 499 protected boolean canEdit(Object element) 500 { 501 return element instanceof CompilerUIOption; 502 } 503 504 @Override 505 protected CellEditor getCellEditor(Object element) 506 { 507 if(element instanceof CompilerUIOption) 508 return ((CompilerUIOption) element).getCellEditor(); 509 else 510 return null; 511 } 512 513 @Override 514 protected Object getValue(Object element) 515 { 516 if(element instanceof CompilerUIOption) 517 return ((CompilerUIOption) element).getValue(); 518 else 519 return null; 520 } 521 522 @Override 523 protected void setValue(Object element, Object value) 524 { 525 if(element instanceof CompilerUIOption) 526 ((CompilerUIOption) element).setValue(value); 527 fViewer.update(element, null); 528 } 529 }); 530 531 GridData gd = new GridData(GridData.FILL_BOTH); 532 fViewer.getControl().setLayoutData(gd); 533 534 fViewer.setContentProvider(new OptionsContentProvider()); 535 } 536 537 private TreeEntry[] getTree() 538 { 539 ICompilerInterface compilerInterface = 540 getCompilerInterface(fSelectedCompiler); 541 Map<String, List<CompilerUIOption>> groups = 542 new TreeMap<String, List<CompilerUIOption>>(); 543 544 for(CompilerOption opt : compilerInterface.getOptions()) 545 { 546 String group = opt.getGroupLabel(); 547 if(!groups.containsKey(group)); 548 groups.put(group, new ArrayList<CompilerUIOption>()); 549 groups.get(group).add(toUIOption(opt)); 550 } 551 552 TreeEntry[] entries = new TreeEntry[groups.size()]; 553 int i = 0; 554 for(String group : groups.keySet()) 555 { 556 List<CompilerUIOption> list = groups.get(group); 557 entries[i] = new TreeEntry(group, 558 list.toArray(new CompilerUIOption[list.size()])); 559 i++; 560 } 561 562 return entries; 563 } 564 565 private CompilerUIOption toUIOption(CompilerOption opt) 566 { 567 if(opt instanceof BooleanOption) 568 return new CheckboxUIOption((BooleanOption) opt); 569 else if(opt instanceof StringOption) 570 return new TextUIOption((StringOption) opt); 571 else if(opt instanceof EnumOption) 572 return new ComboUIOption((EnumOption) opt); 573 else 574 throw new UnsupportedOperationException(); 575 } 576 577 private ICompilerInterface getCompilerInterface(IVMInstall compiler) 578 { 579 // TODO 580 return new DmdCompilerInterface(); 221 581 } 222 582 … … 227 587 228 588 fSelectedCompiler = compiler; 229 // TODO update the displayed options 589 if(null != fViewer && null != fSelectedCompiler) 590 fViewer.setInput(fSelectedCompiler); 230 591 } 231 592 … … 245 606 } 246 607 247 public voidvalidate()608 public String validate() 248 609 { 249 610 // TODO Auto-generated method stub 250 } 611 return null; 612 } 613 } 614 615 //-------------------------------------------------------------------------- 616 // Icon management 617 618 // This needs to be done at the tab level to allow for disposing) 619 620 private Image fCheckedIcon = createImage("obj16/checked.png"); 621 private Image fUncheckedIcon = createImage("obj16/unchecked.png"); 622 623 public void dispose() 624 { 625 super.dispose(); 626 fCheckedIcon.dispose(); 627 fUncheckedIcon.dispose(); 251 628 } 252 629 trunk/descent.building/src/descent/internal/building/ui/GeneralTab.java
r1175 r1177 140 140 } 141 141 142 public voidvalidate()142 public String validate() 143 143 { 144 144 String projectName = fText.getText().trim(); 145 145 if (projectName.length() == 0) 146 { 147 setErrorMessage("Project not defined"); 148 return; 149 } 146 return "Project not defined"; 150 147 151 148 IStatus status = ResourcesPlugin.getWorkspace().validatePath( 152 149 IPath.SEPARATOR + projectName, IResource.PROJECT); 153 150 if (!status.isOK()) 154 { 155 setErrorMessage(String.format("Invalid project name: %$1s", projectName)); 156 return; 157 } 151 return String.format("Invalid project name: %$1s", projectName); 158 152 159 153 IProject project = getWorkspaceRoot().getProject(projectName); 160 154 if (!project.exists()) 161 { 162 setErrorMessage("Project does not exist"); 163 return; 164 } 155 return "Project does not exist"; 165 156 166 157 try 167 158 { 168 159 if (!project.hasNature(JavaCore.NATURE_ID)) 169 { 170 setErrorMessage("Not a D project"); 171 return; 172 } 160 return "Not a D project"; 173 161 } 174 162 catch (Exception e) … … 176 164 // Ignore 177 165 } 166 167 return null; 178 168 } 179 169 } … … 187 177 private Button fExecutableRadio; 188 178 private Button fStaticLibRadio; 179 180 // Note: Okay to use == for comparing this field 181 private String fCurrentSetting; 189 182 190 183 public void addToControl(Composite comp) … … 203 196 if(fExecutableRadio.getSelection()) 204 197 { 205 outputFileSetting.outputTypeChanged(); 206 updateLaunchConfigurationDialog(); 198 if(fCurrentSetting != OUTPUT_TYPE_EXECUTABLE) 199 { 200 fCurrentSetting = OUTPUT_TYPE_EXECUTABLE; 201 outputFileSetting.outputTypeChanged(); 202 updateLaunchConfigurationDialog(); 203 } 207 204 } 208 205 } … … 215 212 if(fStaticLibRadio.getSelection()) 216 213 { 217 outputFileSetting.outputTypeChanged(); 218 updateLaunchConfigurationDialog(); 214 if(fCurrentSetting != OUTPUT_TYPE_STATIC_LIBRARY) 215 { 216 fCurrentSetting = OUTPUT_TYPE_STATIC_LIBRARY; 217 outputFileSetting.outputTypeChanged(); 218 updateLaunchConfigurationDialog(); 219 } 219 220 } 220 221 } … … 232 233 catch(CoreException e) { } 233 234 234 if(outputType.equals(OUTPUT_TYPE_EXECUTABLE)) 235 if(outputType.equals(OUTPUT_TYPE_STATIC_LIBRARY)) 236 { 237 fExecutableRadio.setSelection(false); 238 fStaticLibRadio.setSelection(true); 239 fCurrentSetting = OUTPUT_TYPE_STATIC_LIBRARY; 240 } 241 else 235 242 { 236 243 fExecutableRadio.setSelection(true); 237 244 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); 245 fCurrentSetting = OUTPUT_TYPE_EXECUTABLE; 249 246 } 250 247 } … … 252 249 public void performApply(ILaunchConfigurationWorkingCopy config) 253 250 { 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); 251 config.setAttribute(ATTR_OUTPUT_TYPE, fCurrentSetting); 258 252 } 259 253 … … 263 257 } 264 258 265 public voidvalidate()259 public String validate() 266 260 { 267 261 // Nothing to do -- any choice is valid 262 return null; 268 263 } 269 264 … … 327 322 } 328 323 329 public voidvalidate()324 public String validate() 330 325 { 331 326 String pathText = fText.getText().trim(); 332 327 if (pathText.length() == 0) 333 { 334 setErrorMessage("Output path not defined"); 335 return; 336 } 328 return "Output path not defined"; 337 329 338 330 // No way to check if a file is a valid filename since that's … … 340 332 // sanity checks could be added... but whatever, I'll just handle 341 333 // the error in the builder itself 334 335 return null; 342 336 } 343 337 … … 544 538 } 545 539 546 public voidvalidate()540 public String validate() 547 541 { 548 542 List<String> modules = fList.getElementsNoCopy(); 549 543 550 544 if(modules.isEmpty()) 551 { 552 setErrorMessage("Module list is empty"); 553 return; 554 } 545 return "Module list is empty"; 555 546 556 547 // TODO validate the individual modules... maybe (maybe instead 557 548 // have a check button, since this can be a lengthy operation?) 558 549 550 return null; 559 551 } 560 552 }
