1 13 14 package org.eclipse.jface.viewers; 15 16 import org.eclipse.core.runtime.ListenerList; 17 import org.eclipse.swt.SWT; 18 import org.eclipse.swt.events.FocusAdapter; 19 import org.eclipse.swt.events.FocusEvent; 20 import org.eclipse.swt.events.FocusListener; 21 import org.eclipse.swt.events.MouseAdapter; 22 import org.eclipse.swt.events.MouseEvent; 23 import org.eclipse.swt.events.MouseListener; 24 import org.eclipse.swt.events.TraverseEvent; 25 import org.eclipse.swt.events.TraverseListener; 26 import org.eclipse.swt.widgets.Control; 27 import org.eclipse.swt.widgets.Display; 28 import org.eclipse.swt.widgets.Item; 29 30 38 public abstract class ColumnViewerEditor { 39 private CellEditor cellEditor; 40 41 private ICellEditorListener cellEditorListener; 42 43 private FocusListener focusListener; 44 45 private MouseListener mouseListener; 46 47 private ColumnViewer viewer; 48 49 private TraverseListener tabeditingListener; 50 51 private int activationTime; 52 53 private ViewerCell cell; 54 55 private ColumnViewerEditorActivationEvent activationEvent; 56 57 private ListenerList editorActivationListener; 58 59 private ColumnViewerEditorActivationStrategy editorActivationStrategy; 60 61 64 public static final int DEFAULT = 1; 65 66 70 public static final int TABBING_MOVE_TO_ROW_NEIGHBOR = 1 << 1; 71 72 76 public static final int TABBING_CYCLE_IN_ROW = 1 << 2; 77 78 81 public static final int TABBING_VERTICAL = 1 << 3; 82 83 86 public static final int TABBING_HORIZONTAL = 1 << 4; 87 88 91 public static final int KEYBOARD_ACTIVATION = 1 << 5; 92 93 private int feature; 94 95 110 protected ColumnViewerEditor(ColumnViewer viewer, 111 ColumnViewerEditorActivationStrategy editorActivationStrategy, 112 int feature) { 113 this.viewer = viewer; 114 this.editorActivationStrategy = editorActivationStrategy; 115 if ((feature & KEYBOARD_ACTIVATION) == KEYBOARD_ACTIVATION) { 116 this.editorActivationStrategy 117 .setEnableEditorActivationWithKeyboard(true); 118 } 119 this.feature = feature; 120 initCellEditorListener(); 121 } 122 123 private void initCellEditorListener() { 124 cellEditorListener = new ICellEditorListener() { 125 public void editorValueChanged(boolean oldValidState, 126 boolean newValidState) { 127 } 129 130 public void cancelEditor() { 131 ColumnViewerEditor.this.cancelEditing(); 132 } 133 134 public void applyEditorValue() { 135 ColumnViewerEditor.this.applyEditorValue(); 136 } 137 }; 138 } 139 140 void activateCellEditor() { 141 142 ViewerColumn part = viewer.getViewerColumn(cell.getColumnIndex()); 143 Object element = cell.getElement(); 144 145 if (part != null && part.getEditingSupport() != null 146 && part.getEditingSupport().canEdit(element)) { 147 148 cellEditor = part.getEditingSupport().getCellEditor(element); 149 if (cellEditor != null) { 150 if (editorActivationListener != null 151 && !editorActivationListener.isEmpty()) { 152 Object [] ls = editorActivationListener.getListeners(); 153 for (int i = 0; i < ls.length; i++) { 154 155 if (activationEvent.cancel) { 156 return; 157 } 158 159 ((ColumnViewerEditorActivationListener) ls[i]) 160 .beforeEditorActivated(activationEvent); 161 } 162 } 163 164 updateFocusCell(cell, activationEvent); 165 166 cellEditor.addListener(cellEditorListener); 167 part.getEditingSupport().initializeCellEditorValue(cellEditor, 168 cell); 169 170 final Control control = cellEditor.getControl(); 176 cellEditor.activate(activationEvent); 177 if (control == null) { 178 return; 179 } 180 setLayoutData(cellEditor.getLayoutData()); 181 setEditor(control, (Item) cell.getItem(), cell.getColumnIndex()); 182 cellEditor.setFocus(); 183 184 if( cellEditor.dependsOnExternalFocusListener() ) { 185 if (focusListener == null) { 186 focusListener = new FocusAdapter() { 187 public void focusLost(FocusEvent e) { 188 applyEditorValue(); 189 } 190 }; 191 } 192 control.addFocusListener(focusListener); 193 } 194 195 mouseListener = new MouseAdapter() { 196 public void mouseDown(MouseEvent e) { 197 if (e.time <= activationTime) { 200 control.removeMouseListener(mouseListener); 201 cancelEditing(); 202 handleDoubleClickEvent(); 203 } else if (mouseListener != null) { 204 control.removeMouseListener(mouseListener); 205 } 206 } 207 }; 208 control.addMouseListener(mouseListener); 209 210 if (tabeditingListener == null) { 211 tabeditingListener = new TraverseListener() { 212 213 public void keyTraversed(TraverseEvent e) { 214 if ((feature & DEFAULT) != DEFAULT) { 215 processTraverseEvent(cell.getColumnIndex(), 216 viewer.getViewerRowFromItem(cell 217 .getItem()), e); 218 } 219 } 220 }; 221 } 222 223 control.addTraverseListener(tabeditingListener); 224 225 if (editorActivationListener != null 226 && !editorActivationListener.isEmpty()) { 227 Object [] ls = editorActivationListener.getListeners(); 228 for (int i = 0; i < ls.length; i++) { 229 ((ColumnViewerEditorActivationListener) ls[i]) 230 .afterEditorActivated(activationEvent); 231 } 232 } 233 } 234 } 235 } 236 237 241 void applyEditorValue() { 242 CellEditor c = this.cellEditor; 243 if (c != null && this.cell != null) { 244 ColumnViewerEditorDeactivationEvent tmp = new ColumnViewerEditorDeactivationEvent( 249 cell); 250 if (editorActivationListener != null 251 && !editorActivationListener.isEmpty()) { 252 Object [] ls = editorActivationListener.getListeners(); 253 for (int i = 0; i < ls.length; i++) { 254 255 ((ColumnViewerEditorActivationListener) ls[i]) 256 .beforeEditorDeactivated(tmp); 257 } 258 } 259 260 Item t = (Item) this.cell.getItem(); 261 262 if (t != null && !t.isDisposed()) { 264 saveEditorValue(c); 265 } 266 267 setEditor(null, null, 0); 268 c.removeListener(cellEditorListener); 269 Control control = c.getControl(); 270 if (control != null) { 271 if (mouseListener != null) { 272 control.removeMouseListener(mouseListener); 273 mouseListener = null; 275 } 276 if (focusListener != null) { 277 control.removeFocusListener(focusListener); 278 } 279 280 if (tabeditingListener != null) { 281 control.removeTraverseListener(tabeditingListener); 282 } 283 } 284 c.deactivate(); 285 286 if (editorActivationListener != null 287 && !editorActivationListener.isEmpty()) { 288 Object [] ls = editorActivationListener.getListeners(); 289 for (int i = 0; i < ls.length; i++) { 290 ((ColumnViewerEditorActivationListener) ls[i]) 291 .afterEditorDeactivated(tmp); 292 } 293 } 294 295 this.cellEditor = null; 296 this.activationEvent = null; 297 this.cell = null; 298 } 299 } 300 301 304 void cancelEditing() { 305 if (cellEditor != null) { 306 ColumnViewerEditorDeactivationEvent tmp = new ColumnViewerEditorDeactivationEvent( 307 cell); 308 if (editorActivationListener != null 309 && !editorActivationListener.isEmpty()) { 310 Object [] ls = editorActivationListener.getListeners(); 311 for (int i = 0; i < ls.length; i++) { 312 313 ((ColumnViewerEditorActivationListener) ls[i]) 314 .beforeEditorDeactivated(tmp); 315 } 316 } 317 318 setEditor(null, null, 0); 319 cellEditor.removeListener(cellEditorListener); 320 321 Control control = cellEditor.getControl(); 322 if (control != null) { 323 if (mouseListener != null) { 324 control.removeMouseListener(mouseListener); 325 mouseListener = null; 327 } 328 if (focusListener != null) { 329 control.removeFocusListener(focusListener); 330 } 331 332 if (tabeditingListener != null) { 333 control.removeTraverseListener(tabeditingListener); 334 } 335 } 336 337 CellEditor oldEditor = cellEditor; 338 oldEditor.deactivate(); 339 340 if (editorActivationListener != null 341 && !editorActivationListener.isEmpty()) { 342 Object [] ls = editorActivationListener.getListeners(); 343 for (int i = 0; i < ls.length; i++) { 344 ((ColumnViewerEditorActivationListener) ls[i]) 345 .afterEditorDeactivated(tmp); 346 } 347 } 348 349 this.cellEditor = null; 350 this.activationEvent = null; 351 this.cell = null; 352 } 353 } 354 355 360 void handleEditorActivationEvent(ColumnViewerEditorActivationEvent event) { 361 if (editorActivationStrategy.isEditorActivationEvent(event)) { 362 if (cellEditor != null) { 363 applyEditorValue(); 364 } 365 366 this.cell = (ViewerCell) event.getSource(); 367 368 activationEvent = event; 369 activationTime = event.time 370 + Display.getCurrent().getDoubleClickTime(); 371 372 activateCellEditor(); 373 } 374 } 375 376 private void saveEditorValue(CellEditor cellEditor) { 377 ViewerColumn part = viewer.getViewerColumn(cell.getColumnIndex()); 378 379 if (part != null && part.getEditingSupport() != null) { 380 part.getEditingSupport().saveCellEditorValue(cellEditor, cell); 381 } 382 } 383 384 390 boolean isCellEditorActive() { 391 return cellEditor != null; 392 } 393 394 void handleDoubleClickEvent() { 395 viewer.fireDoubleClick(new DoubleClickEvent(viewer, viewer 396 .getSelection())); 397 viewer.fireOpen(new OpenEvent(viewer, viewer.getSelection())); 398 } 399 400 407 public void addEditorActivationListener( 408 ColumnViewerEditorActivationListener listener) { 409 if (editorActivationListener == null) { 410 editorActivationListener = new ListenerList(); 411 } 412 editorActivationListener.add(listener); 413 } 414 415 421 public void removeEditorActivationListener( 422 ColumnViewerEditorActivationListener listener) { 423 if (editorActivationListener != null) { 424 editorActivationListener.remove(listener); 425 } 426 } 427 428 452 protected void processTraverseEvent(int columnIndex, ViewerRow row, 453 TraverseEvent event) { 454 455 ViewerCell cell2edit = null; 456 457 if (event.detail == SWT.TRAVERSE_TAB_PREVIOUS) { 458 event.doit = false; 459 460 if ((event.stateMask & SWT.CTRL) == SWT.CTRL 461 && (feature & TABBING_VERTICAL) == TABBING_VERTICAL) { 462 cell2edit = searchCellAboveBelow(row, viewer, columnIndex, true); 463 } else if ((feature & TABBING_HORIZONTAL) == TABBING_HORIZONTAL) { 464 cell2edit = searchPreviousCell(row, viewer, columnIndex, 465 columnIndex); 466 } 467 } else if (event.detail == SWT.TRAVERSE_TAB_NEXT) { 468 event.doit = false; 469 470 if ((event.stateMask & SWT.CTRL) == SWT.CTRL 471 && (feature & TABBING_VERTICAL) == TABBING_VERTICAL) { 472 cell2edit = searchCellAboveBelow(row, viewer, columnIndex, 473 false); 474 } else if ((feature & TABBING_HORIZONTAL) == TABBING_HORIZONTAL) { 475 cell2edit = searchNextCell(row, viewer, columnIndex, 476 columnIndex); 477 } 478 } 479 480 if (cell2edit != null) { 481 482 viewer.getControl().setRedraw(false); 483 ColumnViewerEditorActivationEvent acEvent = new ColumnViewerEditorActivationEvent( 484 cell2edit, event); 485 viewer.triggerEditorActivationEvent(acEvent); 486 viewer.getControl().setRedraw(true); 487 } 488 } 489 490 private ViewerCell searchCellAboveBelow(ViewerRow row, ColumnViewer viewer, 491 int columnIndex, boolean above) { 492 ViewerCell rv = null; 493 494 ViewerRow newRow = null; 495 496 if (above) { 497 newRow = row.getNeighbor(ViewerRow.ABOVE, false); 498 } else { 499 newRow = row.getNeighbor(ViewerRow.BELOW, false); 500 } 501 502 if (newRow != null) { 503 ViewerColumn column = viewer.getViewerColumn(columnIndex); 504 if (column != null 505 && column.getEditingSupport() != null 506 && column.getEditingSupport().canEdit( 507 newRow.getItem().getData())) { 508 rv = newRow.getCell(columnIndex); 509 } else { 510 rv = searchCellAboveBelow(newRow, viewer, columnIndex, above); 511 } 512 } 513 514 return rv; 515 } 516 517 private ViewerCell searchPreviousCell(ViewerRow row, ColumnViewer viewer, 518 int columnIndex, int startIndex) { 519 ViewerCell rv = null; 520 521 if (columnIndex - 1 >= 0) { 522 ViewerColumn column = viewer.getViewerColumn(columnIndex - 1); 523 if (column != null 524 && column.getEditingSupport() != null 525 && column.getEditingSupport().canEdit( 526 row.getItem().getData())) { 527 rv = row.getCell(columnIndex - 1); 528 } else { 529 rv = searchPreviousCell(row, viewer, columnIndex - 1, 530 startIndex); 531 } 532 } else { 533 if ((feature & TABBING_CYCLE_IN_ROW) == TABBING_CYCLE_IN_ROW) { 534 if (columnIndex - 1 != startIndex) { 536 rv = searchPreviousCell(row, viewer, row.getColumnCount(), 540 startIndex); 541 } 542 } else if ((feature & TABBING_MOVE_TO_ROW_NEIGHBOR) == TABBING_MOVE_TO_ROW_NEIGHBOR) { 543 ViewerRow rowAbove = row.getNeighbor(ViewerRow.ABOVE, false); 544 if (rowAbove != null) { 545 rv = searchPreviousCell(rowAbove, viewer, rowAbove 546 .getColumnCount(), startIndex); 547 } 548 } 549 } 550 551 return rv; 552 } 553 554 private ViewerCell searchNextCell(ViewerRow row, ColumnViewer viewer, 555 int columnIndex, int startIndex) { 556 ViewerCell rv = null; 557 558 if (columnIndex + 1 < row.getColumnCount()) { 559 ViewerColumn column = viewer.getViewerColumn(columnIndex + 1); 560 if (column != null 561 && column.getEditingSupport() != null 562 && column.getEditingSupport().canEdit( 563 row.getItem().getData())) { 564 rv = row.getCell(columnIndex + 1); 565 } else { 566 rv = searchNextCell(row, viewer, columnIndex + 1, startIndex); 567 } 568 } else { 569 if ((feature & TABBING_CYCLE_IN_ROW) == TABBING_CYCLE_IN_ROW) { 570 if (columnIndex + 1 != startIndex) { 572 rv = searchNextCell(row, viewer, -1, startIndex); 575 } 576 } else if ((feature & TABBING_MOVE_TO_ROW_NEIGHBOR) == TABBING_MOVE_TO_ROW_NEIGHBOR) { 577 ViewerRow rowBelow = row.getNeighbor(ViewerRow.BELOW, false); 578 if (rowBelow != null) { 579 rv = searchNextCell(rowBelow, viewer, -1, startIndex); 580 } 581 } 582 } 583 584 return rv; 585 } 586 587 597 protected abstract void setEditor(Control w, Item item, int fColumnNumber); 598 599 605 protected abstract void setLayoutData(CellEditor.LayoutData layoutData); 606 607 613 protected abstract void updateFocusCell(ViewerCell focusCell, 614 ColumnViewerEditorActivationEvent event); 615 616 622 public ViewerCell getFocusCell() { 623 return null; 624 } 625 626 629 protected ColumnViewer getViewer() { 630 return viewer; 631 } 632 } | Popular Tags |