1 17 package org.eclipse.emf.edit.ui.celleditor; 18 19 20 import org.eclipse.swt.SWT; 21 import org.eclipse.swt.custom.TableTree; 22 import org.eclipse.swt.custom.TableTreeItem; 23 import org.eclipse.swt.events.FocusAdapter; 24 import org.eclipse.swt.events.FocusEvent; 25 import org.eclipse.swt.events.KeyAdapter; 26 import org.eclipse.swt.events.KeyEvent; 27 import org.eclipse.swt.events.KeyListener; 28 import org.eclipse.swt.events.MouseAdapter; 29 import org.eclipse.swt.events.MouseEvent; 30 import org.eclipse.swt.events.PaintEvent; 31 import org.eclipse.swt.events.PaintListener; 32 import org.eclipse.swt.graphics.Color; 33 import org.eclipse.swt.graphics.GC; 34 import org.eclipse.swt.graphics.Image; 35 import org.eclipse.swt.graphics.Point; 36 import org.eclipse.swt.graphics.RGB; 37 import org.eclipse.swt.graphics.Rectangle; 38 import org.eclipse.swt.widgets.Canvas; 39 import org.eclipse.swt.widgets.Composite; 40 import org.eclipse.swt.widgets.Control; 41 import org.eclipse.swt.widgets.Display; 42 import org.eclipse.swt.widgets.Event; 43 import org.eclipse.swt.widgets.Listener; 44 import org.eclipse.swt.widgets.Shell; 45 import org.eclipse.swt.widgets.TableItem; 46 import org.eclipse.swt.widgets.Text; 47 48 import org.eclipse.emf.common.notify.AdapterFactory; 49 import org.eclipse.emf.common.ui.celleditor.ExtendedTableTreeEditor; 50 import org.eclipse.emf.common.ui.viewer.ExtendedTableTreeViewer; 51 import org.eclipse.emf.common.ui.viewer.ExtendedTableTreeViewer.ExtendedTableTreeItem; 52 import org.eclipse.emf.edit.provider.AdapterFactoryItemDelegator; 53 import org.eclipse.emf.edit.provider.IItemPropertyDescriptor; 54 55 56 61 public class AdapterFactoryTableTreeEditor extends ExtendedTableTreeEditor 62 { 63 protected AdapterFactory adapterFactory; 64 protected AdapterFactoryItemDelegator itemDelegator; 65 66 protected TableItem currentTableItem; 67 protected TableTreeItem currentTableTreeItem; 68 protected Object currentTableTreeItemData; 69 protected int currentColumn; 70 71 protected Image leftGradient; 72 protected Image rightGradient; 73 74 protected Composite canvas; 75 76 protected KeyListener keyListener; 77 protected PaintListener paintListener; 78 79 protected Control activeEditor; 80 81 protected boolean isDown; 82 protected boolean hasDropDown; 83 protected boolean hasLaunched; 84 85 public AdapterFactoryTableTreeEditor(TableTree tableTree, AdapterFactory adapterFactory) 86 { 87 super(tableTree); 88 this.adapterFactory = adapterFactory; 89 this.itemDelegator = new AdapterFactoryItemDelegator(adapterFactory); 90 91 keyListener = 92 new KeyAdapter() 93 { 94 public void keyPressed(KeyEvent event) 95 { 96 if (event.character == ' ') 97 { 98 setDown(true); 99 canvas.update(); 100 setDown(false); 101 activate(); 102 } 103 else if (event.character == '\r' || event.character == '\n') 104 { 105 setDown(true); 106 canvas.update(); 107 setDown(false); 108 activate(); 109 } 110 else if (event.character == '\033') 111 { 112 dismiss(); 113 } 114 else if (event.keyCode == SWT.ARROW_LEFT) 115 { 116 arrowLeft(); 117 } 118 else if (event.keyCode == SWT.ARROW_RIGHT) 119 { 120 arrowRight(); 121 } 122 else if (event.keyCode == SWT.ARROW_UP) 123 { 124 arrowUp(); 125 } 126 else if (event.keyCode == SWT.ARROW_DOWN) 127 { 128 arrowDown(); 129 } 130 } 131 }; 132 133 paintListener = 134 new PaintListener() 135 { 136 public void paintControl(PaintEvent event) 137 { 138 AdapterFactoryTableTreeEditor.this.paintControl(event); 139 } 140 }; 141 } 142 143 public AdapterFactory getAdapterFactory() 144 { 145 return adapterFactory; 146 } 147 148 public void setAdapterFactory(AdapterFactory adapterFactory) 149 { 150 this.adapterFactory = adapterFactory; 151 } 152 153 public IItemPropertyDescriptor getColumnPropertyDescriptor(Object object, int column) 154 { 155 return null; 156 } 157 158 public boolean hasInPlaceEditor(Object object, int column) 159 { 160 IItemPropertyDescriptor itemPropertyDescriptor = getColumnPropertyDescriptor(object, column); 161 if (itemPropertyDescriptor != null) 162 { 163 } 164 165 return column == 0; 166 } 167 168 public boolean hasDropDownEditor(Object object, int column) 169 { 170 return column != 0; 171 } 172 173 public Control createDropDownEditor(Composite parent, Object object, int column) 174 { 175 return null; 176 } 177 178 public boolean hasLaunchedEditor(Object object, int column) 179 { 180 return false; 181 } 182 183 public void createLaunchedEditor(Composite parent, Object object, int column) 184 { 185 } 186 187 protected void setDown(boolean isDown) 188 { 189 this.isDown = isDown; 190 canvas.redraw(); 191 } 192 193 protected boolean isDown() 194 { 195 return isDown; 196 } 197 198 protected void editItem(TableItem tableItem, TableTreeItem tableTreeItem, int column) 199 { 200 if (getEditor() != null) 201 { 202 getEditor().dispose(); 203 } 204 205 currentTableItem = tableItem; 206 currentTableTreeItem = tableTreeItem; 207 currentTableTreeItemData = tableTreeItem.getData(); 208 currentColumn = column; 209 210 horizontalAlignment = SWT.LEFT; 211 grabHorizontal = true; 212 minimumWidth = Math.max(50, currentTableTreeItem.getBounds(column).width); 213 214 hasDropDown = hasDropDownEditor(currentTableTreeItemData, currentColumn); 215 hasLaunched = !hasDropDown && hasLaunchedEditor(currentTableTreeItemData, currentColumn); 216 217 canvas = createComposite(); 218 canvas.addKeyListener(keyListener); 219 canvas.addPaintListener(paintListener); 220 221 canvas.addMouseListener 222 (new MouseAdapter() 223 { 224 public void mouseDown(MouseEvent event) 225 { 226 if (event.button == 1) 227 { 228 setDown(true); 229 } 230 } 231 public void mouseUp(MouseEvent event) 232 { 233 if (event.button == 1 && isDown()) 234 { 235 if (currentColumn == 0 && currentTableTreeItem.getItemCount() > 0) 236 { 237 Rectangle imageBounds = adjust( 238 getImageBounds(currentTableItem, 0), 239 currentTableItem.getBounds(currentColumn)); 240 241 if (event.x < imageBounds.x + imageBounds.width + 3) 242 { 243 currentTableTreeItem.setExpanded(!currentTableTreeItem.getExpanded()); 244 Event expandEvent = new Event(); 245 expandEvent.item = currentTableTreeItem; 246 currentTableTreeItem.getParent().notifyListeners(SWT.Expand, expandEvent); 247 } 248 else 249 { 250 activate(); 251 } 252 } 253 else 254 { 255 activate(); 256 } 257 } 258 setDown(false); 259 } 260 }); 261 262 Listener listener = 263 new Listener() 264 { 265 public void handleEvent(Event event) 266 { 267 if (event.type == SWT.Activate) 268 { 269 } 271 else if (event.type == SWT.Deactivate) 272 { 273 } 276 } 277 }; 278 279 canvas.addListener(SWT.Activate, listener); 280 canvas.addListener(SWT.Deactivate, listener); 281 282 setEditor(canvas, currentTableTreeItem, currentColumn); 283 canvas.setFocus(); 284 } 285 286 protected Composite createComposite() 287 { 288 return new Canvas(currentTableItem.getParent(), SWT.NULL); 289 } 290 291 protected void activate() 292 { 293 IItemPropertyDescriptor itemPropertyDescriptor = 295 getColumnPropertyDescriptor(currentTableTreeItem.getData(), currentColumn); 296 if (itemPropertyDescriptor != null || currentColumn != 0 || true) 297 { 298 Rectangle itemBounds = currentTableItem.getBounds(currentColumn); 299 int x = 0; 300 301 if (currentColumn == 0) 304 { 305 Rectangle imageBounds = adjust( 306 getImageBounds(currentTableItem, currentColumn), itemBounds); 307 x += imageBounds.x + imageBounds.width; 308 } 309 310 Point point = currentTableItem.getParent().toDisplay( 311 new Point(itemBounds.x, itemBounds.y)); 312 313 final Shell dropDown = new Shell( 314 currentTableItem.getParent().getShell(), SWT.ON_TOP | SWT.NO_TRIM); 315 dropDown.setBackground( 316 dropDown.getDisplay().getSystemColor(SWT.COLOR_BLACK)); 317 dropDown.setBounds(point.x + x, point.y + itemBounds.height, itemBounds.width - x, itemBounds.height * 5); 318 319 final Control control = 320 hasDropDownEditor(currentTableTreeItem.getData(), currentColumn) ? 321 createDropDownEditor(dropDown, currentTableTreeItem.getData(), currentColumn) : 322 null; 323 324 if (control != null) 325 { 326 control.setBounds(1, 1, itemBounds.width - x - 2, itemBounds.height * 5 - 2); 327 328 dropDown.setVisible(true); 329 dropDown.layout(); 330 control.setFocus(); 331 332 Listener dropDownListener = 333 new Listener() 334 { 335 public void handleEvent(Event e) 336 { 337 switch (e.type) 338 { 339 case SWT.Close: 340 { 341 cancel(); 343 dropDown.dispose(); 344 break; 345 } 346 case SWT.Deactivate: 347 { 348 apply(); 350 dropDown.dispose(); 351 break; 352 } 353 365 } 366 } 367 }; 368 369 dropDown.addListener(SWT.Close, dropDownListener); 370 dropDown.addListener(SWT.Deactivate, dropDownListener); 372 373 control.addMouseListener 374 (new MouseAdapter() 375 { 376 public void mouseDoubleClick(MouseEvent event) 377 { 378 if (event.button == 1) 379 { 380 apply(); 381 dropDown.dispose(); 382 } 383 } 384 }); 385 386 control.addKeyListener 387 (new KeyAdapter() 388 { 389 public void keyPressed(KeyEvent e) 390 { 391 if (e.character == ' ' || e.character == '\r' || e.character == '\n') 392 { 393 apply(); 394 dropDown.dispose(); 395 } 396 else if (e.character == '\033') 397 { 398 cancel(); 399 dropDown.dispose(); 400 } 401 } 402 }); 403 } 404 else if (hasLaunchedEditor(currentTableTreeItem.getData(), currentColumn)) 405 { 406 createLaunchedEditor(dropDown, currentTableTreeItem.getData(), currentColumn); 407 } 408 409 activeEditor = control; 410 } 411 else 412 { 413 final Text text = new Text(canvas, SWT.NULL); 414 canvas.setLayout 415 (new org.eclipse.swt.widgets.Layout() 416 { 417 protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) 418 { 419 return canvas.getSize(); 420 } 421 422 protected void layout(Composite composite, boolean flushCache) 423 { 424 if (text.isDisposed()) 425 { 426 return; 427 } 428 429 Rectangle itemBounds = currentTableItem.getBounds(currentColumn); 430 Rectangle imageBounds = adjust( 431 getImageBounds(currentTableItem, currentColumn), itemBounds); 432 int paddingWidth = 433 currentColumn == 0 && currentTableTreeItem instanceof ExtendedTableTreeItem ? 434 ((ExtendedTableTreeItem)currentTableTreeItem).getImagePaddingWidth() : 435 0; 436 437 int x = paddingWidth == 0 ? 3 : paddingWidth; 440 x += imageBounds.x + imageBounds.width; 441 442 text.setBounds(x, 1, itemBounds.width - 1 - x, itemBounds.height - 2); 443 } 444 }); 445 String columnText = currentTableTreeItem.getText(currentColumn); 446 text.setText(columnText); 447 text.setVisible(true); 448 text.setFocus(); 449 text.addKeyListener 450 (new KeyAdapter() 451 { 452 public void keyPressed(KeyEvent e) 453 { 454 if (e.character == '\r' || e.character == '\n') 455 { 456 apply(); 457 text.dispose(); 458 } 459 else if (e.character == '\033') 460 { 461 cancel(); 462 text.dispose(); 463 } 464 } 465 }); 466 text.addFocusListener 467 (new FocusAdapter() 468 { 469 public void focusLost(FocusEvent e) 470 { 471 apply(); 472 text.dispose(); 473 } 474 }); 475 canvas.layout(); 476 text.setSelection(0, columnText.length()); 477 text.showSelection(); 478 479 activeEditor = text; 480 } 481 } 482 483 public void cancel() 484 { 485 activeEditor = null; 486 } 487 488 public void apply() 489 { 490 activeEditor = null; 491 if (canvas != null && canvas.isDisposed()) 492 { 493 canvas.redraw(); 494 } 495 } 496 497 public void dismiss() 498 { 499 if (canvas != null) 500 { 501 canvas.dispose(); 502 canvas = null; 503 super.dismiss(); 504 } 506 } 507 508 protected void arrowLeft() 509 { 510 if (currentColumn > 0) 511 { 512 editItem(currentTableItem, currentTableTreeItem, currentColumn - 1); 513 } 514 else 515 { 516 if (currentTableTreeItem.getItemCount() > 0) 517 { 518 currentTableTreeItem.setExpanded(!currentTableTreeItem.getExpanded()); 519 Event expandEvent = new Event(); 520 expandEvent.item = currentTableTreeItem; 521 currentTableTreeItem.getParent().notifyListeners(SWT.Expand, expandEvent); 522 } 523 } 524 } 525 protected void arrowRight() 526 { 527 if (currentColumn + 1 < currentTableItem.getParent().getColumnCount()) 528 { 529 editItem(currentTableItem, currentTableTreeItem, currentColumn + 1); 530 } 531 } 532 533 protected void arrowUp() 534 { 535 int index = currentTableItem.getParent().indexOf(currentTableItem); 536 if (index > 0) 537 { 538 TableItem newTableItem = currentTableItem.getParent().getItem(index - 1); 539 currentTableItem.getParent().showItem(newTableItem); 540 currentTableItem.getParent().setSelection(index - 1); 541 editItem(newTableItem, (TableTreeItem)newTableItem.getData(ExtendedTableTreeViewer.ITEM_ID), currentColumn); 542 } 543 } 544 545 protected void arrowDown() 546 { 547 int index = currentTableItem.getParent().indexOf(currentTableItem); 548 if (index + 1 < currentTableItem.getParent().getItemCount()) 549 { 550 TableItem newTableItem = currentTableItem.getParent().getItem(index + 1); 551 currentTableItem.getParent().showItem(newTableItem); 552 currentTableItem.getParent().setSelection(index + 1); 553 editItem(newTableItem, (TableTreeItem)newTableItem.getData(ExtendedTableTreeViewer.ITEM_ID), currentColumn); 554 } 555 } 556 557 protected static Rectangle adjust(Rectangle bounds, Rectangle baseBounds) 558 { 559 bounds.x -= baseBounds.x; 560 bounds.y -= baseBounds.y; 561 return bounds; 562 } 563 564 protected static Rectangle getImageBounds(TableItem item, int column) 565 { 566 return ExtendedTableTreeViewer.getImageBounds(item, column); 567 } 568 569 protected static void drawImage(GC gc, Image image, Rectangle bounds) 570 { 571 Rectangle imageBounds = image.getBounds(); 572 gc.drawImage(image, 573 imageBounds.x, imageBounds.y, imageBounds.width, imageBounds.height, 574 bounds.x, bounds.y, bounds.width, bounds.height); 575 } 576 577 public void paintControl(PaintEvent event) 578 { 579 if (currentTableItem.isDisposed()) 580 { 581 apply(); 582 dismiss(); 583 TableItem [] tableItems = table.getItems(); 584 for (int i = 0; i < tableItems.length; ++i) 585 { 586 TableTreeItem tableTreeItem = (TableTreeItem)tableItems[i].getData(ExtendedTableTreeViewer.ITEM_ID); 587 if (tableTreeItem.getData() == currentTableTreeItemData) 588 { 589 editItem(tableItems[i], tableTreeItem, currentColumn); 590 } 591 } 592 593 return; 594 } 595 596 Display display = currentTableItem.getDisplay(); 597 Rectangle itemBounds = currentTableItem.getBounds(currentColumn); 598 599 String text = currentTableTreeItem.getText(currentColumn); 600 Image image = currentTableItem.getImage(currentColumn); 601 Rectangle imageBounds = adjust( 602 getImageBounds(currentTableItem, currentColumn), itemBounds); 603 604 Image extraImage = null; 607 Rectangle extraImageBounds = null; 608 int paddingWidth = 0; 609 610 if (currentColumn == 0 && 611 currentTableTreeItem instanceof ExtendedTableTreeItem) 612 { 613 ExtendedTableTreeItem item = (ExtendedTableTreeItem)currentTableTreeItem; 614 extraImage = item.getFirstImage(); 615 extraImageBounds = adjust(item.getFirstImageBounds(), itemBounds); 616 paddingWidth = item.getImagePaddingWidth(); 617 } 618 619 event.gc.setBackground(display.getSystemColor(SWT.COLOR_LIST_BACKGROUND)); 622 event.gc.fillRectangle(event.x, event.y, event.width, event.height); 623 624 if (image != null) drawImage(event.gc, image, imageBounds); 627 if (extraImage != null) drawImage(event.gc, extraImage, extraImageBounds); 628 629 if (text != null) 632 { 633 int x = paddingWidth == 0 ? 3 : paddingWidth; 637 x += imageBounds.x + imageBounds.width + 3; 638 639 int width = event.gc.stringExtent(text).x; 640 int height = event.gc.stringExtent(text).y; 641 int y = height < itemBounds.height ? 642 (itemBounds.height + 1 - height) / 2 : 0; 643 644 event.gc.setForeground(display.getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT)); 645 event.gc.setBackground(display.getSystemColor(SWT.COLOR_LIST_SELECTION)); 646 647 event.gc.fillRectangle(x - 3, 0, width + 8, itemBounds.height); 648 event.gc.drawString(text, x, y, true); 649 } 650 651 int boxX = itemBounds.width - itemBounds.height; 654 int boxY = itemBounds.height - 1; 655 if (hasLaunched || hasDropDown) 656 { 657 event.gc.setBackground(display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); 658 event.gc.fillPolygon 659 (new int [] 660 { 661 boxX, boxY, 662 boxX + itemBounds.height - 1, boxY, 663 boxX + itemBounds.height - 1, 1, 664 boxX, 1 665 }); 666 } 667 668 if (hasDropDown) 671 { 672 event.gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK)); 673 int baseX = itemBounds.width - itemBounds.height / 2 - 1; 674 int baseY = itemBounds.height - itemBounds.height / 2 + 3; 675 if (isDown()) 676 { 677 baseX += 1; 678 baseY += 1; 679 } 680 event.gc.fillPolygon 681 (new int [] 682 { 683 baseX, baseY, 684 baseX + 4, baseY - 4, 685 baseX - 3, baseY - 4 686 }); 687 } 688 else if (hasLaunched) 691 { 692 event.gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK)); 693 event.gc.setBackground(display.getSystemColor(SWT.COLOR_WIDGET_BACKGROUND)); 694 int baseX = itemBounds.width - itemBounds.height / 2 - 1; 695 int baseY = 0; 696 if (isDown()) 697 { 698 baseX += 1; 699 baseY += 1; 700 } 701 event.gc.drawString("...", itemBounds.width - (itemBounds.height + event.gc.stringExtent("...").x) / 2, baseY); 702 } 703 704 event.gc.setForeground(display.getSystemColor(SWT.COLOR_DARK_GRAY)); 707 event.gc.drawRectangle(0, 0, itemBounds.width - 1, itemBounds.height - 1); 708 709 if (hasLaunched || hasDropDown) 712 { 713 if (isDown()) 714 { 715 event.gc.setForeground(display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); 716 event.gc.drawLine(boxX, boxY - 1, boxX, 1); 717 event.gc.drawLine(boxX, 1, boxX + itemBounds.height - 1, 1); 718 719 event.gc.drawLine(boxX + 1, boxY - 1, boxX + itemBounds.height - 1, boxY - 1); 720 event.gc.drawLine(boxX + itemBounds.height - 1, boxY - 1, boxX + itemBounds.height - 1, 2); 721 } 722 else 723 { 724 event.gc.setForeground(display.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW)); 725 event.gc.drawLine(boxX + 1, boxY - 1, boxX + 1, 2); 726 event.gc.drawLine(boxX + 1, 2, boxX + itemBounds.height - 2, 2); 727 728 event.gc.setForeground(display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)); 729 event.gc.drawLine(boxX + 1, boxY - 2, boxX + itemBounds.height - 3, boxY - 2); 730 event.gc.drawLine(boxX + itemBounds.height - 3, boxY - 2, boxX + itemBounds.height - 3, 2); 731 732 event.gc.setForeground(display.getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW)); 733 event.gc.drawLine(boxX, boxY - 1, boxX + itemBounds.height - 2, boxY - 1); 734 event.gc.drawLine(boxX + itemBounds.height - 2, boxY - 1, boxX + itemBounds.height - 2, 1); 735 } 736 } 737 } 738 739 protected Image getLeftGradient() 740 { 741 if (leftGradient == null) 742 { 743 getGradients(); 744 } 745 746 return leftGradient; 747 } 748 749 protected Image getRightGradient() 750 { 751 if (rightGradient == null) 752 { 753 getGradients(); 754 } 755 756 return rightGradient; 757 } 758 759 protected void getGradients() 760 { 761 int width = 20; 762 int height = 10; 763 764 Display display = canvas.getDisplay(); 765 766 leftGradient = new Image(display, width, height); 767 GC leftGC = new GC(leftGradient); 768 769 rightGradient = new Image(display, width, height); 770 GC rightGC = new GC(rightGradient); 771 772 Color startColor = display.getSystemColor(SWT.COLOR_LIST_BACKGROUND); 774 RGB rgb1 = startColor.getRGB(); 775 776 Color endColor = display.getSystemColor(SWT.COLOR_LIST_BACKGROUND); 777 RGB rgb2 = endColor.getRGB(); 778 779 for (int k = 0; k < width; k++) 780 { 781 int r = rgb1.red + k * (rgb2.red - rgb1.red) / width; 782 r = (rgb2.red > rgb1.red) ? Math.min(r, rgb2.red) : Math.max(r, rgb2.red); 783 int g = rgb1.green + k * (rgb2.green - rgb1.green) / width; 784 g = (rgb2.green > rgb1.green) ? Math.min(g, rgb2.green) : Math.max(g, rgb2.green); 785 int b = rgb1.blue + k * (rgb2.blue - rgb1.blue) / width; 786 b = (rgb2.blue > rgb1.blue) ? Math.min(b, rgb2.blue) : Math.max(b, rgb2.blue); 787 788 Color color = new Color(display, r, g, b); 789 790 leftGC.setBackground(color); 791 leftGC.fillRectangle(width - k - 1, 0, 1, height); 792 793 rightGC.setBackground(color); 794 rightGC.fillRectangle(k, 0, 1, height); 795 796 color.dispose(); 797 } 798 799 leftGC.dispose(); 800 rightGC.dispose(); 801 } 802 } 803 804 805 832 833 | Popular Tags |