1 13 package org.eclipse.ui.internal.ide.misc; 14 15 import java.text.Collator ; 16 import java.util.ArrayList ; 17 import java.util.Arrays ; 18 import java.util.Collection ; 19 import java.util.Collections ; 20 import java.util.Comparator ; 21 import java.util.HashMap ; 22 import java.util.Hashtable ; 23 import java.util.Iterator ; 24 import java.util.LinkedList ; 25 import java.util.Map ; 26 27 import org.eclipse.jface.dialogs.MessageDialog; 28 import org.eclipse.jface.resource.ImageDescriptor; 29 import org.eclipse.jface.viewers.CheckStateChangedEvent; 30 import org.eclipse.jface.viewers.CheckboxTableViewer; 31 import org.eclipse.jface.viewers.ICheckStateListener; 32 import org.eclipse.jface.viewers.IContentProvider; 33 import org.eclipse.jface.viewers.ISelection; 34 import org.eclipse.jface.viewers.ISelectionChangedListener; 35 import org.eclipse.jface.viewers.IStructuredSelection; 36 import org.eclipse.jface.viewers.LabelProvider; 37 import org.eclipse.jface.viewers.ListViewer; 38 import org.eclipse.jface.viewers.SelectionChangedEvent; 39 import org.eclipse.jface.viewers.StructuredSelection; 40 import org.eclipse.osgi.util.NLS; 41 import org.eclipse.swt.SWT; 42 import org.eclipse.swt.graphics.Font; 43 import org.eclipse.swt.graphics.Image; 44 import org.eclipse.swt.layout.GridData; 45 import org.eclipse.swt.layout.GridLayout; 46 import org.eclipse.swt.widgets.Composite; 47 import org.eclipse.swt.widgets.Control; 48 import org.eclipse.swt.widgets.Label; 49 import org.eclipse.swt.widgets.Text; 50 import org.eclipse.ui.internal.ide.Category; 51 import org.eclipse.ui.internal.ide.IDEWorkbenchMessages; 52 import org.eclipse.ui.internal.ide.registry.Capability; 53 import org.eclipse.ui.internal.ide.registry.CapabilityRegistry; 54 import org.eclipse.ui.model.WorkbenchContentProvider; 55 import org.eclipse.ui.model.WorkbenchLabelProvider; 56 57 61 public class ProjectCapabilitySelectionGroup { 62 private static final String EMPTY_DESCRIPTION = "\n\n\n"; 64 private CapabilityRegistry registry; 65 66 private Category[] initialCategories; 67 68 private Capability[] initialCapabilities; 69 70 private Capability[] disabledCapabilities; 71 72 private boolean modified = false; 73 74 private Text descriptionText; 75 76 private CheckboxTableViewer checkboxViewer; 77 78 private ICheckStateListener checkStateListener; 79 80 private ArrayList visibleCapabilities = new ArrayList (); 81 82 private ArrayList checkedCapabilities = new ArrayList (); 83 84 private Collection disabledCaps; 85 86 private HashMap dependents = new HashMap (); 91 92 private HashMap memberships = new HashMap (); 95 96 private Comparator categoryComparator = new Comparator () { 98 private Collator collator = Collator.getInstance(); 99 100 public int compare(Object ob1, Object ob2) { 101 Category c1 = (Category) ob1; 102 Category c2 = (Category) ob2; 103 return collator.compare(c1.getLabel(), c2.getLabel()); 104 } 105 }; 106 107 private Comparator capabilityComparator = new Comparator () { 109 private Collator collator = Collator.getInstance(); 110 111 public int compare(Object ob1, Object ob2) { 112 Capability c1 = (Capability) ob1; 113 Capability c2 = (Capability) ob2; 114 return collator.compare(c1.getName(), c2.getName()); 115 } 116 }; 117 118 125 public ProjectCapabilitySelectionGroup(Category[] categories, 126 Capability[] capabilities, CapabilityRegistry registry) { 127 this(categories, capabilities, null, registry); 128 } 129 130 138 public ProjectCapabilitySelectionGroup(Category[] categories, 139 Capability[] capabilities, Capability[] disabledCapabilities, 140 CapabilityRegistry registry) { 141 super(); 142 this.initialCategories = categories; 143 this.initialCapabilities = capabilities; 144 this.disabledCapabilities = disabledCapabilities; 145 this.registry = registry; 146 } 147 148 153 public Control createContents(Composite parent) { 154 Font font = parent.getFont(); 155 Composite composite = new Composite(parent, SWT.NONE); 157 GridLayout layout = new GridLayout(); 158 layout.numColumns = 2; 159 layout.makeColumnsEqualWidth = true; 160 composite.setLayout(layout); 161 composite.setLayoutData(new GridData(GridData.FILL_BOTH)); 162 163 Composite catComposite = new Composite(composite, SWT.NONE); 165 catComposite.setLayout(new GridLayout()); 166 catComposite.setLayoutData(new GridData(GridData.FILL_BOTH)); 167 168 Label categoryLabel = new Label(catComposite, SWT.LEFT); 170 categoryLabel.setText(IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_categories); 171 GridData data = new GridData(); 172 data.verticalAlignment = SWT.TOP; 173 categoryLabel.setLayoutData(data); 174 categoryLabel.setFont(font); 175 176 ListViewer listViewer = new ListViewer(catComposite); 178 listViewer.getList().setLayoutData(new GridData(GridData.FILL_BOTH)); 179 listViewer.getList().setFont(font); 180 listViewer.setLabelProvider(new WorkbenchLabelProvider()); 181 listViewer.setContentProvider(getContentProvider()); 182 listViewer.setInput(getAvailableCategories()); 183 184 Composite capComposite = new Composite(composite, SWT.NONE); 186 capComposite.setLayout(new GridLayout()); 187 capComposite.setLayoutData(new GridData(GridData.FILL_BOTH)); 188 189 Label capabilityLabel = new Label(capComposite, SWT.LEFT); 191 capabilityLabel.setText(IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_capabilities); 192 data = new GridData(); 193 data.verticalAlignment = SWT.TOP; 194 capabilityLabel.setLayoutData(data); 195 capabilityLabel.setFont(font); 196 197 checkboxViewer = CheckboxTableViewer.newCheckList(capComposite, 199 SWT.SINGLE | SWT.TOP | SWT.BORDER); 200 checkboxViewer.getTable().setLayoutData( 201 new GridData(GridData.FILL_BOTH)); 202 checkboxViewer.getTable().setFont(font); 203 checkboxViewer.setLabelProvider(new CapabilityLabelProvider()); 204 checkboxViewer.setContentProvider(getContentProvider()); 205 checkboxViewer.setInput(visibleCapabilities); 206 207 Label descLabel = new Label(composite, SWT.LEFT); 209 descLabel.setText(IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_description); 210 data = new GridData(); 211 data.verticalAlignment = SWT.TOP; 212 data.horizontalSpan = 2; 213 descLabel.setLayoutData(data); 214 descLabel.setFont(font); 215 216 descriptionText = new Text(composite, SWT.WRAP | SWT.MULTI 218 | SWT.V_SCROLL | SWT.BORDER); 219 descriptionText.setText(EMPTY_DESCRIPTION); 220 descriptionText.setEditable(false); 221 data = new GridData(); 222 data.horizontalAlignment = GridData.FILL; 223 data.grabExcessHorizontalSpace = true; 224 data.horizontalSpan = 2; 225 descriptionText.setLayoutData(data); 226 descriptionText.setFont(font); 227 228 Label grayLabel = new Label(composite, SWT.LEFT); 230 grayLabel.setText(IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_grayItems); 231 data = new GridData(); 232 data.verticalAlignment = SWT.TOP; 233 data.horizontalSpan = 2; 234 grayLabel.setLayoutData(data); 235 grayLabel.setFont(font); 236 237 populateDependents(); 239 populateMemberships(); 240 241 checkboxViewer 243 .addSelectionChangedListener(new ISelectionChangedListener() { 244 public void selectionChanged(SelectionChangedEvent event) { 245 updateDescription(event.getSelection()); 246 } 247 }); 248 249 checkboxViewer.addCheckStateListener(new ICheckStateListener() { 251 public void checkStateChanged(CheckStateChangedEvent event) { 252 Capability cap = (Capability) event.getElement(); 253 if (event.getChecked()) 254 handleCapabilityChecked(cap); 255 else 256 handleCapabilityUnchecked(cap); 257 checkboxViewer.setSelection(new StructuredSelection(cap)); 258 } 259 }); 260 261 listViewer.addSelectionChangedListener(new ISelectionChangedListener() { 263 public void selectionChanged(SelectionChangedEvent event) { 264 if (event.getSelection() instanceof IStructuredSelection) { 265 IStructuredSelection sel = (IStructuredSelection) event 266 .getSelection(); 267 visibleCapabilities.clear(); 268 Iterator itr = sel.iterator(); 269 while (itr.hasNext()) { 270 Category cat = (Category) itr.next(); 271 visibleCapabilities.addAll(cat.getElements()); 272 } 273 Collections.sort(visibleCapabilities, capabilityComparator); 274 checkboxViewer.refresh(); 275 itr = visibleCapabilities.iterator(); 276 while (itr.hasNext()) { 277 Capability cap = (Capability) itr.next(); 278 if (hasDependency(cap)) 279 checkboxViewer.setGrayed(cap, true); 280 if (checkedCapabilities.contains(cap)) 281 checkboxViewer.setChecked(cap, true); 282 } 283 updateDescription(checkboxViewer.getSelection()); 284 } 285 } 286 }); 287 288 if (initialCapabilities != null) 290 checkedCapabilities.addAll(Arrays.asList(initialCapabilities)); 291 if (initialCategories != null) 292 listViewer.setSelection(new StructuredSelection(initialCategories)); 293 294 return composite; 295 } 296 297 300 private void markCapabilityChecked(Capability target, Capability dependent) { 301 if (!checkedCapabilities.contains(target)) 303 checkedCapabilities.add(target); 304 checkboxViewer.setChecked(target, true); 305 306 if (target != dependent) 309 checkboxViewer.setGrayed(target, true); 310 311 addDependency(target, dependent); 313 314 String [] ids = registry.getMembershipSetIds(target); 316 for (int j = 0; j < ids.length; j++) 317 memberships.put(ids[j], target); 318 } 319 320 323 private void markCapabilityUnchecked(Capability target) { 324 checkedCapabilities.remove(target); 326 checkboxViewer.setChecked(target, false); 327 328 checkboxViewer.setGrayed(target, false); 330 331 dependents.remove(target); 333 334 String [] ids = registry.getMembershipSetIds(target); 336 for (int j = 0; j < ids.length; j++) { 337 if (memberships.get(ids[j]) == target) 338 memberships.remove(ids[j]); 339 } 340 } 341 342 346 private ArrayList getAvailableCategories() { 347 ArrayList results = registry.getUsedCategories(); 348 Collections.sort(results, categoryComparator); 349 if (registry.getMiscCategory() != null) 350 results.add(registry.getMiscCategory()); 351 return results; 352 } 353 354 362 public boolean getCapabilitiesModified() { 363 return modified; 364 } 365 366 369 private IContentProvider getContentProvider() { 370 return new WorkbenchContentProvider() { 371 public Object [] getChildren(Object parentElement) { 372 if (parentElement instanceof ArrayList ) 373 return ((ArrayList ) parentElement).toArray(); 374 else 375 return null; 376 } 377 }; 378 } 379 380 384 private void capabilitiesModified() { 385 modified = true; 386 } 387 388 392 private void addDependency(Capability target, Capability dependent) { 393 ArrayList descriptors = (ArrayList ) dependents.get(target); 394 if (descriptors == null) { 395 descriptors = new ArrayList (); 396 descriptors.add(dependent); 397 dependents.put(target, descriptors); 398 } else if (!descriptors.contains(dependent)) { 399 descriptors.add(dependent); 400 } 401 } 402 403 407 private boolean hasDependency(Capability capability) { 408 ArrayList descriptors = (ArrayList ) dependents.get(capability); 409 if (descriptors == null) 410 return false; 411 if (descriptors.size() == 1 && descriptors.get(0) == capability) 412 return false; 413 return true; 414 } 415 416 419 private boolean isDisabledCapability(Capability cap) { 420 if (disabledCaps == null) { 421 if (disabledCapabilities == null) 422 disabledCaps = new ArrayList (0); 423 else 424 disabledCaps = Arrays.asList(disabledCapabilities); 425 } 426 return disabledCaps.contains(cap); 427 } 428 429 433 private void populateDependents() { 434 if (initialCapabilities == null) 435 return; 436 437 LinkedList capabilities = new LinkedList (); 438 capabilities.addAll(Arrays.asList(initialCapabilities)); 439 440 while (!capabilities.isEmpty()) { 441 Capability target; 443 target = (Capability) capabilities.removeFirst(); 444 addDependency(target, target); 449 450 if (registry.hasPrerequisites(target)) { 451 String [] prereqIds = registry.getPrerequisiteIds(target); 453 Capability[] prereqCapabilities; 454 prereqCapabilities = registry.findCapabilities(prereqIds); 455 for (int i = 0; i < prereqCapabilities.length; i++) { 457 addDependency(prereqCapabilities[i], target); 459 if (registry.hasPrerequisites(prereqCapabilities[i])) 461 capabilities.addLast(prereqCapabilities[i]); 462 } 463 } 464 } 465 } 466 467 471 private void populateMemberships() { 472 if (initialCapabilities == null) 473 return; 474 475 Iterator itr = (Arrays.asList(initialCapabilities)).iterator(); 476 while (itr.hasNext()) { 477 Capability cap = (Capability) itr.next(); 478 String [] ids = registry.getMembershipSetIds(cap); 479 for (int j = 0; j < ids.length; j++) { 480 memberships.put(ids[j], cap); 481 } 482 } 483 } 484 485 490 private void handleCapabilityChecked(Capability capability) { 491 if (isDisabledCapability(capability)) { 493 MessageDialog 494 .openWarning( 495 checkboxViewer.getControl().getShell(), 496 IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_errorTitle, 497 NLS.bind(IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_disabledCapability, capability.getName())); 498 checkboxViewer.setChecked(capability, false); 499 return; 500 } 501 502 if (!capability.isValid()) { 504 MessageDialog 505 .openWarning( 506 checkboxViewer.getControl().getShell(), 507 IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_errorTitle, 508 NLS.bind(IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_invalidCapability, capability.getName())); 509 checkboxViewer.setChecked(capability, false); 510 return; 511 } 512 513 String [] ids = registry.getMembershipSetIds(capability); 515 for (int i = 0; i < ids.length; i++) { 516 Capability member = (Capability) memberships.get(ids[i]); 517 if (member != null && member != capability) { 518 MessageDialog 519 .openWarning( 520 checkboxViewer.getControl().getShell(), 521 IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_errorTitle, 522 NLS.bind(IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_membershipConflict, capability.getName(), member.getName())); 523 checkboxViewer.setChecked(capability, false); 524 return; 525 } 526 } 527 528 if (registry.hasPrerequisites(capability)) { 530 LinkedList capabilities = new LinkedList (); 534 capabilities.addLast(capability); 535 while (!capabilities.isEmpty()) { 536 Capability target; 537 target = (Capability) capabilities.removeFirst(); 538 String [] prereqIds = registry.getPrerequisiteIds(target); 540 Capability[] prereqCapabilities; 541 prereqCapabilities = registry.findCapabilities(prereqIds); 542 for (int i = 0; i < prereqCapabilities.length; i++) { 543 if (prereqCapabilities[i] == null 546 || isDisabledCapability(prereqCapabilities[i]) 547 || !prereqCapabilities[i].isValid()) { 548 MessageDialog 549 .openWarning( 550 checkboxViewer.getControl().getShell(), 551 IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_errorTitle, 552 NLS.bind(IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_missingPrereqs, capability.getName(), prereqIds[i])); 553 checkboxViewer.setChecked(capability, false); 554 return; 555 } 556 ids = registry.getMembershipSetIds(prereqCapabilities[i]); 559 for (int j = 0; j < ids.length; j++) { 560 Capability member = (Capability) memberships 561 .get(ids[j]); 562 if (member != null && member != prereqCapabilities[i]) { 563 MessageDialog 564 .openWarning( 565 checkboxViewer.getControl() 566 .getShell(), 567 IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_errorTitle, 568 NLS.bind(IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_membershipPrereqConflict, new Object [] {capability.getName(), prereqCapabilities[i].getName(), member.getName()})); 569 checkboxViewer.setChecked(capability, false); 570 return; 571 } 572 } 573 if (registry.hasPrerequisites(prereqCapabilities[i])) 576 capabilities.addLast(prereqCapabilities[i]); 577 } 578 } 579 580 capabilities = new LinkedList (); 582 capabilities.addLast(capability); 583 while (!capabilities.isEmpty()) { 585 Capability target; 586 target = (Capability) capabilities.removeFirst(); 587 String [] prereqIds = registry.getPrerequisiteIds(target); 589 Capability[] prereqCapabilities; 590 prereqCapabilities = registry.findCapabilities(prereqIds); 591 for (int i = 0; i < prereqCapabilities.length; i++) { 593 markCapabilityChecked(prereqCapabilities[i], target); 595 if (registry.hasPrerequisites(prereqCapabilities[i])) 597 capabilities.addLast(prereqCapabilities[i]); 598 } 599 } 600 } 601 602 markCapabilityChecked(capability, capability); 607 608 capabilitiesModified(); 610 notifyCheckStateListner(); 611 } 612 613 617 private void handleCapabilityUnchecked(Capability capability) { 618 ArrayList descriptors = (ArrayList ) dependents.get(capability); 619 620 627 if (descriptors.size() == 1 && descriptors.get(0) == capability) { 628 capabilitiesModified(); 630 markCapabilityUnchecked(capability); 631 632 if (registry.hasPrerequisites(capability)) { 636 LinkedList capabilities = new LinkedList (); 637 capabilities.addLast(capability); 638 while (!capabilities.isEmpty()) { 640 Capability target; 641 target = (Capability) capabilities.removeFirst(); 642 String [] prereqIds = registry.getPrerequisiteIds(target); 644 Capability[] prereqCapabilities; 645 prereqCapabilities = registry.findCapabilities(prereqIds); 646 for (int i = 0; i < prereqCapabilities.length; i++) { 648 Capability prereqCap = prereqCapabilities[i]; 650 ArrayList prereqDependents = (ArrayList ) dependents 651 .get(prereqCap); 652 prereqDependents.remove(target); 654 if (prereqDependents.isEmpty()) { 655 markCapabilityUnchecked(prereqCap); 657 if (registry.hasPrerequisites(prereqCap)) 660 capabilities.addLast(prereqCap); 661 } else if (prereqDependents.size() == 1 662 && prereqDependents.get(0) == prereqCap) { 663 checkboxViewer.setGrayed(prereqCap, false); 666 } 667 } 668 } 669 } 670 671 notifyCheckStateListner(); 673 } else { 674 checkboxViewer.setChecked(capability, true); 677 ArrayList descCopy = (ArrayList ) descriptors.clone(); 679 descCopy.remove(capability); 680 if (descCopy.size() == 1) { 682 Capability cap = (Capability) descCopy.get(0); 683 MessageDialog 684 .openWarning( 685 checkboxViewer.getControl().getShell(), 686 IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_errorTitle, 687 NLS.bind(IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_requiredPrereq, capability.getName(), cap.getName())); 688 } else { 689 StringBuffer msg = new StringBuffer (); 690 Iterator itr = descCopy.iterator(); 691 while (itr.hasNext()) { 692 Capability cap = (Capability) itr.next(); 693 msg.append("\n "); msg.append(cap.getName()); 695 } 696 MessageDialog 697 .openWarning( 698 checkboxViewer.getControl().getShell(), 699 IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_errorTitle, 700 NLS.bind(IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_requiredPrereqs, capability.getName(), msg)); 701 } 702 } 703 } 704 705 712 public Capability[] getSelectedCapabilities() { 713 Capability[] capabilities = new Capability[checkedCapabilities.size()]; 714 checkedCapabilities.toArray(capabilities); 715 return capabilities; 716 } 717 718 724 public ICheckStateListener getCheckStateListener() { 725 return checkStateListener; 726 } 727 728 734 public void setCheckStateListener(ICheckStateListener checkStateListener) { 735 this.checkStateListener = checkStateListener; 736 } 737 738 744 private void notifyCheckStateListner() { 745 if (checkStateListener != null) 746 checkStateListener.checkStateChanged(null); 747 } 748 749 752 private void updateDescription(ISelection selection) { 753 String text = EMPTY_DESCRIPTION; 754 if (selection instanceof IStructuredSelection) { 755 IStructuredSelection sel = (IStructuredSelection) selection; 756 Capability cap = (Capability) sel.getFirstElement(); 757 if (cap != null) 758 text = cap.getDescription(); 759 } 760 descriptionText.setText(text); 761 } 762 763 class CapabilityLabelProvider extends LabelProvider { 764 private Map imageTable; 765 766 public void dispose() { 767 if (imageTable != null) { 768 Iterator itr = imageTable.values().iterator(); 769 while (itr.hasNext()) 770 ((Image) itr.next()).dispose(); 771 imageTable = null; 772 } 773 } 774 775 public Image getImage(Object element) { 776 ImageDescriptor descriptor = ((Capability) element) 777 .getIconDescriptor(); 778 if (descriptor == null) 779 return null; 780 781 if (imageTable == null) { 783 imageTable = new Hashtable (40); 784 } 785 Image image = (Image) imageTable.get(descriptor); 786 if (image == null) { 787 image = descriptor.createImage(); 788 imageTable.put(descriptor, image); 789 } 790 return image; 791 } 792 793 public String getText(Object element) { 794 Capability cap = (Capability) element; 795 String text = cap.getName(); 796 if (isDisabledCapability(cap)) 797 text = NLS.bind(IDEWorkbenchMessages.ProjectCapabilitySelectionGroup_disabledLabel, text ); 798 return text; 799 } 800 } 801 } 802 803 | Popular Tags |