1 11 package org.eclipse.jdt.internal.ui.wizards.dialogfields; 12 13 import java.util.ArrayList ; 14 import java.util.Collection ; 15 import java.util.Iterator ; 16 import java.util.List ; 17 18 import org.eclipse.core.runtime.Assert; 19 20 import org.eclipse.swt.SWT; 21 import org.eclipse.swt.events.KeyAdapter; 22 import org.eclipse.swt.events.KeyEvent; 23 import org.eclipse.swt.events.SelectionEvent; 24 import org.eclipse.swt.events.SelectionListener; 25 import org.eclipse.swt.layout.GridData; 26 import org.eclipse.swt.layout.GridLayout; 27 import org.eclipse.swt.widgets.Button; 28 import org.eclipse.swt.widgets.Composite; 29 import org.eclipse.swt.widgets.Control; 30 import org.eclipse.swt.widgets.Display; 31 import org.eclipse.swt.widgets.Label; 32 import org.eclipse.swt.widgets.Table; 33 import org.eclipse.swt.widgets.TableColumn; 34 35 import org.eclipse.jface.viewers.ColumnLayoutData; 36 import org.eclipse.jface.viewers.ColumnWeightData; 37 import org.eclipse.jface.viewers.DoubleClickEvent; 38 import org.eclipse.jface.viewers.IDoubleClickListener; 39 import org.eclipse.jface.viewers.ILabelProvider; 40 import org.eclipse.jface.viewers.ISelection; 41 import org.eclipse.jface.viewers.ISelectionChangedListener; 42 import org.eclipse.jface.viewers.IStructuredContentProvider; 43 import org.eclipse.jface.viewers.IStructuredSelection; 44 import org.eclipse.jface.viewers.SelectionChangedEvent; 45 import org.eclipse.jface.viewers.StructuredSelection; 46 import org.eclipse.jface.viewers.TableLayout; 47 import org.eclipse.jface.viewers.TableViewer; 48 import org.eclipse.jface.viewers.Viewer; 49 import org.eclipse.jface.viewers.ViewerComparator; 50 import org.eclipse.jface.viewers.ViewerSorter; 51 52 import org.eclipse.jdt.internal.ui.util.PixelConverter; 53 import org.eclipse.jdt.internal.ui.util.SWTUtil; 54 import org.eclipse.jdt.internal.ui.util.TableLayoutComposite; 55 56 62 public class ListDialogField extends DialogField { 63 64 public static class ColumnsDescription { 65 private ColumnLayoutData[] columns; 66 private String [] headers; 67 private boolean drawLines; 68 69 public ColumnsDescription(ColumnLayoutData[] columns, String [] headers, boolean drawLines) { 70 this.columns= columns; 71 this.headers= headers; 72 this.drawLines= drawLines; 73 } 74 75 public ColumnsDescription(String [] headers, boolean drawLines) { 76 this(createColumnWeightData(headers.length), headers, drawLines); 77 } 78 79 public ColumnsDescription(int nColumns, boolean drawLines) { 80 this(createColumnWeightData(nColumns), null, drawLines); 81 } 82 83 private static ColumnLayoutData[] createColumnWeightData(int nColumns) { 84 ColumnLayoutData[] data= new ColumnLayoutData[nColumns]; 85 for (int i= 0; i < nColumns; i++) { 86 data[i]= new ColumnWeightData(1); 87 } 88 return data; 89 } 90 } 91 92 protected TableViewer fTable; 93 protected Control fTableControl; 94 protected ILabelProvider fLabelProvider; 95 protected ListViewerAdapter fListViewerAdapter; 96 protected List fElements; 97 protected ViewerComparator fViewerComparator; 98 99 protected String [] fButtonLabels; 100 private Button[] fButtonControls; 101 102 private boolean[] fButtonsEnabled; 103 104 private int fRemoveButtonIndex; 105 private int fUpButtonIndex; 106 private int fDownButtonIndex; 107 108 private Label fLastSeparator; 109 110 111 private Composite fButtonsControl; 112 private ISelection fSelectionWhenEnabled; 113 114 private IListAdapter fListAdapter; 115 116 private Object fParentElement; 117 118 private ColumnsDescription fTableColumns; 119 120 121 129 public ListDialogField(IListAdapter adapter, String [] buttonLabels, ILabelProvider lprovider) { 130 super(); 131 fListAdapter= adapter; 132 133 fLabelProvider= lprovider; 134 fListViewerAdapter= new ListViewerAdapter(); 135 fParentElement= this; 136 137 fElements= new ArrayList (10); 138 139 fButtonLabels= buttonLabels; 140 if (fButtonLabels != null) { 141 int nButtons= fButtonLabels.length; 142 fButtonsEnabled= new boolean[nButtons]; 143 for (int i= 0; i < nButtons; i++) { 144 fButtonsEnabled[i]= true; 145 } 146 } 147 148 fTable= null; 149 fTableControl= null; 150 fButtonsControl= null; 151 fTableColumns= null; 152 153 fRemoveButtonIndex= -1; 154 fUpButtonIndex= -1; 155 fDownButtonIndex= -1; 156 } 157 158 163 public void setRemoveButtonIndex(int removeButtonIndex) { 164 Assert.isTrue(removeButtonIndex < fButtonLabels.length); 165 fRemoveButtonIndex= removeButtonIndex; 166 } 167 168 173 public void setUpButtonIndex(int upButtonIndex) { 174 Assert.isTrue(upButtonIndex < fButtonLabels.length); 175 fUpButtonIndex= upButtonIndex; 176 } 177 178 183 public void setDownButtonIndex(int downButtonIndex) { 184 Assert.isTrue(downButtonIndex < fButtonLabels.length); 185 fDownButtonIndex= downButtonIndex; 186 } 187 188 192 public void setViewerComparator(ViewerComparator viewerComparator) { 193 fViewerComparator= viewerComparator; 194 } 195 196 public void setTableColumns(ColumnsDescription column) { 197 fTableColumns= column; 198 } 199 200 201 202 204 private void buttonPressed(int index) { 205 if (!managedButtonPressed(index) && fListAdapter != null) { 206 fListAdapter.customButtonPressed(this, index); 207 } 208 } 209 210 214 protected boolean managedButtonPressed(int index) { 215 if (index == fRemoveButtonIndex) { 216 remove(); 217 } else if (index == fUpButtonIndex) { 218 up(); 219 if (!fButtonControls[index].isEnabled() && fDownButtonIndex != -1) { 220 fButtonControls[fDownButtonIndex].setFocus(); 221 } 222 } else if (index == fDownButtonIndex) { 223 down(); 224 if (!fButtonControls[index].isEnabled() && fUpButtonIndex != -1) { 225 fButtonControls[fUpButtonIndex].setFocus(); 226 } 227 } else { 228 return false; 229 } 230 return true; 231 } 232 233 234 236 239 public Control[] doFillIntoGrid(Composite parent, int nColumns) { 240 PixelConverter converter= new PixelConverter(parent); 241 242 assertEnoughColumns(nColumns); 243 244 Label label= getLabelControl(parent); 245 GridData gd= gridDataForLabel(1); 246 gd.verticalAlignment= GridData.BEGINNING; 247 label.setLayoutData(gd); 248 249 Control list= getListControl(parent); 250 gd= new GridData(); 251 gd.horizontalAlignment= GridData.FILL; 252 gd.grabExcessHorizontalSpace= false; 253 gd.verticalAlignment= GridData.FILL; 254 gd.grabExcessVerticalSpace= true; 255 gd.horizontalSpan= nColumns - 2; 256 gd.widthHint= converter.convertWidthInCharsToPixels(50); 257 gd.heightHint= converter.convertHeightInCharsToPixels(6); 258 259 list.setLayoutData(gd); 260 261 Composite buttons= getButtonBox(parent); 262 gd= new GridData(); 263 gd.horizontalAlignment= GridData.FILL; 264 gd.grabExcessHorizontalSpace= false; 265 gd.verticalAlignment= GridData.FILL; 266 gd.grabExcessVerticalSpace= true; 267 gd.horizontalSpan= 1; 268 buttons.setLayoutData(gd); 269 270 return new Control[] { label, list, buttons }; 271 } 272 273 276 public int getNumberOfControls() { 277 return 3; 278 } 279 280 283 public void setButtonsMinWidth(int minWidth) { 284 if (fLastSeparator != null) { 285 ((GridData)fLastSeparator.getLayoutData()).widthHint= minWidth; 286 } 287 } 288 289 290 292 297 public Control getListControl(Composite parent) { 298 if (fTableControl == null) { 299 assertCompositeNotNull(parent); 300 301 if (fTableColumns == null) { 302 fTable= createTableViewer(parent); 303 Table tableControl= fTable.getTable(); 304 305 fTableControl= tableControl; 306 tableControl.setLayout(new TableLayout()); 307 } else { 308 TableLayoutComposite composite= new TableLayoutComposite(parent, SWT.NONE); 309 composite.setFont(parent.getFont()); 310 fTableControl= composite; 311 312 fTable= createTableViewer(composite); 313 Table tableControl= fTable.getTable(); 314 315 tableControl.setHeaderVisible(fTableColumns.headers != null); 316 tableControl.setLinesVisible(fTableColumns.drawLines); 317 ColumnLayoutData[] columns= fTableColumns.columns; 318 for (int i= 0; i < columns.length; i++) { 319 composite.addColumnData(columns[i]); 320 TableColumn column= new TableColumn(tableControl, SWT.NONE); 321 if (fTableColumns.headers != null) { 323 column.setText(fTableColumns.headers[i]); 324 } 325 } 326 } 327 328 fTable.getTable().addKeyListener(new KeyAdapter() { 329 public void keyPressed(KeyEvent e) { 330 handleKeyPressed(e); 331 } 332 }); 333 334 336 fTable.setContentProvider(fListViewerAdapter); 337 fTable.setLabelProvider(fLabelProvider); 338 fTable.addSelectionChangedListener(fListViewerAdapter); 339 fTable.addDoubleClickListener(fListViewerAdapter); 340 341 fTable.setInput(fParentElement); 342 343 if (fViewerComparator != null) { 344 fTable.setComparator(fViewerComparator); 345 } 346 347 fTableControl.setEnabled(isEnabled()); 348 if (fSelectionWhenEnabled != null) { 349 selectElements(fSelectionWhenEnabled); 350 } 351 } 352 return fTableControl; 353 } 354 355 358 public TableViewer getTableViewer() { 359 return fTable; 360 } 361 362 365 protected int getListStyle(){ 366 int style= SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL ; 367 if (fTableColumns != null) { 368 style |= SWT.FULL_SELECTION; 369 } 370 return style; 371 } 372 373 protected TableViewer createTableViewer(Composite parent) { 374 Table table= new Table(parent, getListStyle()); 375 table.setFont(parent.getFont()); 376 return new TableViewer(table); 377 } 378 379 protected Button createButton(Composite parent, String label, SelectionListener listener) { 380 Button button= new Button(parent, SWT.PUSH); 381 button.setFont(parent.getFont()); 382 button.setText(label); 383 button.addSelectionListener(listener); 384 GridData gd= new GridData(); 385 gd.horizontalAlignment= GridData.FILL; 386 gd.grabExcessHorizontalSpace= true; 387 gd.verticalAlignment= GridData.BEGINNING; 388 gd.widthHint = SWTUtil.getButtonWidthHint(button); 389 390 button.setLayoutData(gd); 391 392 return button; 393 } 394 395 private Label createSeparator(Composite parent) { 396 Label separator= new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); 397 separator.setFont(parent.getFont()); 398 separator.setVisible(false); 399 GridData gd= new GridData(); 400 gd.horizontalAlignment= GridData.FILL; 401 gd.verticalAlignment= GridData.BEGINNING; 402 gd.verticalIndent= 4; 403 separator.setLayoutData(gd); 404 return separator; 405 } 406 407 413 public Composite getButtonBox(Composite parent) { 414 if (fButtonsControl == null) { 415 assertCompositeNotNull(parent); 416 417 SelectionListener listener= new SelectionListener() { 418 public void widgetDefaultSelected(SelectionEvent e) { 419 doButtonSelected(e); 420 } 421 public void widgetSelected(SelectionEvent e) { 422 doButtonSelected(e); 423 } 424 }; 425 426 Composite contents= new Composite(parent, SWT.NONE); 427 contents.setFont(parent.getFont()); 428 GridLayout layout= new GridLayout(); 429 layout.marginWidth= 0; 430 layout.marginHeight= 0; 431 contents.setLayout(layout); 432 433 if (fButtonLabels != null) { 434 fButtonControls= new Button[fButtonLabels.length]; 435 for (int i= 0; i < fButtonLabels.length; i++) { 436 String currLabel= fButtonLabels[i]; 437 if (currLabel != null) { 438 fButtonControls[i]= createButton(contents, currLabel, listener); 439 fButtonControls[i].setEnabled(isEnabled() && fButtonsEnabled[i]); 440 } else { 441 fButtonControls[i]= null; 442 createSeparator(contents); 443 } 444 } 445 } 446 447 fLastSeparator= createSeparator(contents); 448 449 updateButtonState(); 450 fButtonsControl= contents; 451 } 452 453 return fButtonsControl; 454 } 455 456 private void doButtonSelected(SelectionEvent e) { 457 if (fButtonControls != null) { 458 for (int i= 0; i < fButtonControls.length; i++) { 459 if (e.widget == fButtonControls[i]) { 460 buttonPressed(i); 461 return; 462 } 463 } 464 } 465 } 466 467 471 protected void handleKeyPressed(KeyEvent event) { 472 if (event.character == SWT.DEL && event.stateMask == 0) { 473 if (fRemoveButtonIndex != -1 && isButtonEnabled(fTable.getSelection(), fRemoveButtonIndex)) { 474 managedButtonPressed(fRemoveButtonIndex); 475 } 476 } 477 } 478 479 481 484 public void dialogFieldChanged() { 485 super.dialogFieldChanged(); 486 updateButtonState(); 487 } 488 489 492 protected void updateButtonState() { 493 if (fButtonControls != null && isOkToUse(fTableControl) && fTableControl.isEnabled()) { 494 ISelection sel= fTable.getSelection(); 495 for (int i= 0; i < fButtonControls.length; i++) { 496 Button button= fButtonControls[i]; 497 if (isOkToUse(button)) { 498 button.setEnabled(isButtonEnabled(sel, i)); 499 } 500 } 501 } 502 } 503 504 protected boolean getManagedButtonState(ISelection sel, int index) { 505 if (index == fRemoveButtonIndex) { 506 return !sel.isEmpty(); 507 } else if (index == fUpButtonIndex) { 508 return !sel.isEmpty() && canMoveUp(); 509 } else if (index == fDownButtonIndex) { 510 return !sel.isEmpty() && canMoveDown(); 511 } 512 return true; 513 } 514 515 518 protected void updateEnableState() { 519 super.updateEnableState(); 520 521 boolean enabled= isEnabled(); 522 if (isOkToUse(fTableControl)) { 523 if (!enabled) { 524 if (fSelectionWhenEnabled == null) { 525 fSelectionWhenEnabled= fTable.getSelection(); 526 selectElements(null); 527 } 528 } else if (fSelectionWhenEnabled != null) { 529 selectElements(fSelectionWhenEnabled); 530 fSelectionWhenEnabled= null; 531 } 532 fTableControl.setEnabled(enabled); 533 } 534 updateButtonState(); 535 } 536 537 540 public void enableButton(int index, boolean enable) { 541 if (fButtonsEnabled != null && index < fButtonsEnabled.length) { 542 fButtonsEnabled[index]= enable; 543 updateButtonState(); 544 } 545 } 546 547 private boolean isButtonEnabled(ISelection sel, int index) { 548 boolean extraState= getManagedButtonState(sel, index); 549 return isEnabled() && extraState && fButtonsEnabled[index]; 550 } 551 552 553 555 558 public void setElements(Collection elements) { 559 fElements= new ArrayList (elements); 560 if (isOkToUse(fTableControl)) { 561 fTable.refresh(); 562 } 563 dialogFieldChanged(); 564 } 565 566 570 public List getElements() { 571 return new ArrayList (fElements); 572 } 573 574 577 public Object getElement(int index) { 578 return fElements.get(index); 579 } 580 581 584 public int getIndexOfElement(Object elem) { 585 return fElements.indexOf(elem); 586 } 587 588 591 public void replaceElement(Object oldElement, Object newElement) throws IllegalArgumentException { 592 int idx= fElements.indexOf(oldElement); 593 if (idx != -1) { 594 fElements.set(idx, newElement); 595 if (isOkToUse(fTableControl)) { 596 List selected= getSelectedElements(); 597 if (selected.remove(oldElement)) { 598 selected.add(newElement); 599 } 600 fTable.refresh(); 601 selectElements(new StructuredSelection(selected)); 602 } 603 dialogFieldChanged(); 604 } else { 605 throw new IllegalArgumentException (); 606 } 607 } 608 609 612 public void elementChanged(Object element) throws IllegalArgumentException { 613 if (fElements.contains(element)) { 614 if (isOkToUse(fTableControl)) { 615 fTable.update(element, null); 616 } 617 dialogFieldChanged(); 618 } else { 619 throw new IllegalArgumentException (); 620 } 621 } 622 623 626 public boolean addElement(Object element) { 627 return addElement(element, fElements.size()); 628 } 629 630 633 public boolean addElement(Object element, int index) { 634 if (fElements.contains(element)) { 635 return false; 636 } 637 fElements.add(index, element); 638 if (isOkToUse(fTableControl)) { 639 fTable.refresh(); 640 fTable.setSelection(new StructuredSelection(element)); 641 } 642 643 dialogFieldChanged(); 644 return true; 645 } 646 647 650 public boolean addElements(List elements, int index) { 651 652 int nElements= elements.size(); 653 654 if (nElements > 0 && index >= 0 && index <= fElements.size()) { 655 ArrayList elementsToAdd= new ArrayList (nElements); 657 658 for (int i= 0; i < nElements; i++) { 659 Object elem= elements.get(i); 660 if (!fElements.contains(elem)) { 661 elementsToAdd.add(elem); 662 } 663 } 664 if (!elementsToAdd.isEmpty()) { 665 fElements.addAll(index, elementsToAdd); 666 if (isOkToUse(fTableControl)) { 667 if (index == fElements.size()) { 668 fTable.add(elementsToAdd.toArray()); 669 } else { 670 for (int i= elementsToAdd.size() - 1; i >= 0 ; i--) { 671 fTable.insert(elementsToAdd.get(i), index); 672 } 673 } 674 fTable.setSelection(new StructuredSelection(elementsToAdd)); 675 } 676 dialogFieldChanged(); 677 return true; 678 } 679 } 680 return false; 681 } 682 683 686 public boolean addElements(List elements) { 687 return addElements(elements, fElements.size()); 688 } 689 690 691 692 695 public void removeAllElements() { 696 if (fElements.size() > 0) { 697 fElements.clear(); 698 if (isOkToUse(fTableControl)) { 699 fTable.refresh(); 700 } 701 dialogFieldChanged(); 702 } 703 } 704 705 708 public void removeElement(Object element) throws IllegalArgumentException { 709 if (fElements.remove(element)) { 710 if (isOkToUse(fTableControl)) { 711 fTable.remove(element); 712 } 713 dialogFieldChanged(); 714 } else { 715 throw new IllegalArgumentException (); 716 } 717 } 718 719 722 public void removeElements(List elements) { 723 if (elements.size() > 0) { 724 fElements.removeAll(elements); 725 if (isOkToUse(fTableControl)) { 726 fTable.remove(elements.toArray()); 727 } 728 dialogFieldChanged(); 729 } 730 } 731 732 735 public int getSize() { 736 return fElements.size(); 737 } 738 739 740 public void selectElements(ISelection selection) { 741 fSelectionWhenEnabled= selection; 742 if (isOkToUse(fTableControl)) { 743 fTable.setSelection(selection, true); 744 } 745 } 746 747 public void selectFirstElement() { 748 Object element= null; 749 if (fViewerComparator != null) { 750 Object [] arr= fElements.toArray(); 751 fViewerComparator.sort(fTable, arr); 752 if (arr.length > 0) { 753 element= arr[0]; 754 } 755 } else { 756 if (fElements.size() > 0) { 757 element= fElements.get(0); 758 } 759 } 760 if (element != null) { 761 selectElements(new StructuredSelection(element)); 762 } 763 } 764 765 public void editElement(Object element) { 766 if (isOkToUse(fTableControl)) { 767 fTable.refresh(element); 768 fTable.editElement(element, 0); 769 } 770 } 771 772 773 public void postSetSelection(final ISelection selection) { 774 if (isOkToUse(fTableControl)) { 775 Display d= fTableControl.getDisplay(); 776 d.asyncExec(new Runnable () { 777 public void run() { 778 if (isOkToUse(fTableControl)) { 779 selectElements(selection); 780 } 781 } 782 }); 783 } 784 } 785 786 789 public void refresh() { 790 super.refresh(); 791 if (isOkToUse(fTableControl)) { 792 fTable.refresh(); 793 } 794 } 795 796 798 private List moveUp(List elements, List move) { 799 int nElements= elements.size(); 800 List res= new ArrayList (nElements); 801 Object floating= null; 802 for (int i= 0; i < nElements; i++) { 803 Object curr= elements.get(i); 804 if (move.contains(curr)) { 805 res.add(curr); 806 } else { 807 if (floating != null) { 808 res.add(floating); 809 } 810 floating= curr; 811 } 812 } 813 if (floating != null) { 814 res.add(floating); 815 } 816 return res; 817 } 818 819 private void moveUp(List toMoveUp) { 820 if (toMoveUp.size() > 0) { 821 setElements(moveUp(fElements, toMoveUp)); 822 fTable.reveal(toMoveUp.get(0)); 823 } 824 } 825 826 private void moveDown(List toMoveDown) { 827 if (toMoveDown.size() > 0) { 828 setElements(reverse(moveUp(reverse(fElements), toMoveDown))); 829 fTable.reveal(toMoveDown.get(toMoveDown.size() - 1)); 830 } 831 } 832 833 private List reverse(List p) { 834 List reverse= new ArrayList (p.size()); 835 for (int i= p.size()-1; i >= 0; i--) { 836 reverse.add(p.get(i)); 837 } 838 return reverse; 839 } 840 841 842 private void remove() { 843 removeElements(getSelectedElements()); 844 } 845 846 private void up() { 847 moveUp(getSelectedElements()); 848 } 849 850 private void down() { 851 moveDown(getSelectedElements()); 852 } 853 854 public boolean canMoveUp() { 855 if (isOkToUse(fTableControl)) { 856 int[] indc= fTable.getTable().getSelectionIndices(); 857 for (int i= 0; i < indc.length; i++) { 858 if (indc[i] != i) { 859 return true; 860 } 861 } 862 } 863 return false; 864 } 865 866 public boolean canMoveDown() { 867 if (isOkToUse(fTableControl)) { 868 int[] indc= fTable.getTable().getSelectionIndices(); 869 int k= fElements.size() - 1; 870 for (int i= indc.length - 1; i >= 0 ; i--, k--) { 871 if (indc[i] != k) { 872 return true; 873 } 874 } 875 } 876 return false; 877 } 878 879 882 public List getSelectedElements() { 883 List result= new ArrayList (); 884 if (isOkToUse(fTableControl)) { 885 ISelection selection= fTable.getSelection(); 886 if (selection instanceof IStructuredSelection) { 887 Iterator iter= ((IStructuredSelection)selection).iterator(); 888 while (iter.hasNext()) { 889 result.add(iter.next()); 890 } 891 } 892 } 893 return result; 894 } 895 896 898 private class ListViewerAdapter implements IStructuredContentProvider, ISelectionChangedListener, IDoubleClickListener { 899 900 902 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { 903 } 905 906 public boolean isDeleted(Object element) { 907 return false; 908 } 909 910 public void dispose() { 911 } 912 913 public Object [] getElements(Object obj) { 914 return fElements.toArray(); 915 } 916 917 919 public void selectionChanged(SelectionChangedEvent event) { 920 doListSelected(event); 921 } 922 923 926 public void doubleClick(DoubleClickEvent event) { 927 doDoubleClick(event); 928 } 929 930 } 931 932 933 protected void doListSelected(SelectionChangedEvent event) { 934 updateButtonState(); 935 if (fListAdapter != null) { 936 fListAdapter.selectionChanged(this); 937 } 938 } 939 940 protected void doDoubleClick(DoubleClickEvent event) { 941 if (fListAdapter != null) { 942 fListAdapter.doubleClicked(this); 943 } 944 } 945 946 949 public void setViewerSorter(ViewerSorter sorter) { 950 setViewerComparator(sorter); 951 } 952 953 } 954 | Popular Tags |