KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > debug > internal > ui > views > memory > renderings > AsyncTableRenderingViewer


1 /*******************************************************************************
2  * Copyright (c) 2006, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.debug.internal.ui.views.memory.renderings;
13
14 import java.math.BigInteger JavaDoc;
15
16 import org.eclipse.core.runtime.IProgressMonitor;
17 import org.eclipse.core.runtime.IStatus;
18 import org.eclipse.core.runtime.Status;
19 import org.eclipse.debug.internal.ui.DebugUIMessages;
20 import org.eclipse.debug.internal.ui.DebugUIPlugin;
21 import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
22 import org.eclipse.debug.internal.ui.memory.provisional.AbstractAsyncTableRendering;
23 import org.eclipse.debug.internal.ui.viewers.AbstractUpdatePolicy;
24 import org.eclipse.debug.internal.ui.viewers.AsynchronousModel;
25 import org.eclipse.debug.internal.ui.viewers.model.provisional.IStatusMonitor;
26 import org.eclipse.debug.internal.ui.views.memory.MemoryViewUtil;
27 import org.eclipse.jface.resource.JFaceResources;
28 import org.eclipse.jface.viewers.CellEditor;
29 import org.eclipse.jface.viewers.IBaseLabelProvider;
30 import org.eclipse.jface.viewers.ICellEditorListener;
31 import org.eclipse.jface.viewers.ICellModifier;
32 import org.eclipse.jface.viewers.ILabelProviderListener;
33 import org.eclipse.jface.viewers.ITableLabelProvider;
34 import org.eclipse.jface.viewers.SelectionChangedEvent;
35 import org.eclipse.jface.viewers.StructuredSelection;
36 import org.eclipse.jface.viewers.TextCellEditor;
37 import org.eclipse.swt.SWT;
38 import org.eclipse.swt.custom.TableCursor;
39 import org.eclipse.swt.custom.TableEditor;
40 import org.eclipse.swt.events.DisposeEvent;
41 import org.eclipse.swt.events.DisposeListener;
42 import org.eclipse.swt.events.KeyAdapter;
43 import org.eclipse.swt.events.KeyEvent;
44 import org.eclipse.swt.events.MouseAdapter;
45 import org.eclipse.swt.events.MouseEvent;
46 import org.eclipse.swt.events.SelectionAdapter;
47 import org.eclipse.swt.events.SelectionEvent;
48 import org.eclipse.swt.events.TraverseEvent;
49 import org.eclipse.swt.events.TraverseListener;
50 import org.eclipse.swt.graphics.Image;
51 import org.eclipse.swt.graphics.Rectangle;
52 import org.eclipse.swt.widgets.Composite;
53 import org.eclipse.swt.widgets.Control;
54 import org.eclipse.swt.widgets.Display;
55 import org.eclipse.swt.widgets.Table;
56 import org.eclipse.swt.widgets.TableItem;
57 import org.eclipse.swt.widgets.Text;
58 import org.eclipse.swt.widgets.Widget;
59 import org.eclipse.ui.progress.UIJob;
60
61 public class AsyncTableRenderingViewer extends AsyncVirtualContentTableViewer {
62
63     private AbstractAsyncTableRendering fRendering;
64     
65     // selection keys
66
private Object JavaDoc fPendingSelection;
67     private Object JavaDoc fSelectionKey;
68     
69     // cursor and associated listeners
70
private TableCursor fTableCursor;
71     private KeyAdapter fCursorKeyAdapter;
72     private TraverseListener fCursorTraverseListener;
73     private MouseAdapter fCursorMouseListener;
74     private SelectionAdapter fCursorSelectionListener;
75
76     // cursor editor and associated listeners
77
private TableEditor fCursorEditor;
78     private KeyAdapter fEditorKeyListener;
79     private CellEditorListener fCellEditorListener;
80     
81     private class CellEditorListener implements ICellEditorListener {
82
83         private CellEditor fEditor;
84         private int fRow;
85         private int fCol;
86         
87         public CellEditorListener(int row, int col, CellEditor editor) {
88             fEditor = editor;
89             fRow = row;
90             fCol = col;
91         }
92         
93         public void applyEditorValue() {
94             fEditor.removeListener(this);
95             modifyValue(fRow, fCol, fEditor.getValue());
96         }
97
98         public void cancelEditor() {
99             fEditor.removeListener(this);
100         }
101         
102         public void editorValueChanged(boolean oldValidState,
103                 boolean newValidState) {
104         }
105         
106         public int getRow()
107         {
108             return fRow;
109         }
110         
111         public int getCol()
112         {
113             return fCol;
114         }
115     }
116
117     private boolean fPendingFormatViewer;
118
119     
120     public AsyncTableRenderingViewer(AbstractAsyncTableRendering rendering, Composite parent, int style) {
121         super(parent, style);
122         fRendering = rendering;
123         
124         getTable().addMouseListener(new MouseAdapter() {
125             public void mouseDown(MouseEvent e) {
126                 handleTableMouseEvent(e);
127             }});
128         
129         createCursor(getTable());
130     }
131
132     public AbstractUpdatePolicy createUpdatePolicy() {
133         return new AsyncTableRenderingUpdatePolicy();
134     }
135     
136     public AbstractAsyncTableRendering getRendering()
137     {
138         return fRendering;
139     }
140     
141     private void createCursor(Table table)
142     {
143         fTableCursor = new TableCursor(table, SWT.NONE);
144         
145         Display display = fTableCursor.getDisplay();
146         
147         // set up cursor color
148
fTableCursor.setBackground(display.getSystemColor(SWT.COLOR_LIST_SELECTION));
149         fTableCursor.setForeground(display.getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT));
150         
151         fTableCursor.setFont(JFaceResources.getFont(IInternalDebugUIConstants.FONT_NAME));
152         
153         fCursorKeyAdapter = new KeyAdapter() {
154             public void keyPressed(KeyEvent e)
155              {
156                 handleCursorKeyPressed(e);
157              }
158         };
159         
160         fTableCursor.addKeyListener(fCursorKeyAdapter);
161         
162         fCursorTraverseListener = new TraverseListener() {
163             public void keyTraversed(TraverseEvent e) {
164                 handleCursorTraverseEvt(e);
165             }};
166                     
167         fTableCursor.addTraverseListener(fCursorTraverseListener);
168         
169         fCursorMouseListener = new MouseAdapter() {
170             public void mouseDown(MouseEvent e) {
171                 handleCursorMouseEvent(e);
172             }};
173         fTableCursor.addMouseListener(fCursorMouseListener);
174         
175         // cursor may be disposed before disposed is called
176
// remove listeners whenever the cursor is disposed
177
fTableCursor.addDisposeListener(new DisposeListener() {
178             public void widgetDisposed(DisposeEvent e) {
179                 if (fTableCursor == null)
180                     return;
181                 fTableCursor.removeTraverseListener(fCursorTraverseListener);
182                 fTableCursor.removeKeyListener(fCursorKeyAdapter);
183                 fTableCursor.removeMouseListener(fCursorMouseListener);
184                 fTableCursor.removeSelectionListener(fCursorSelectionListener);
185             }});
186         
187         fCursorSelectionListener = new SelectionAdapter() {
188                     public void widgetSelected(SelectionEvent e) {
189                         handleCursorMoved();
190                     }
191                 };
192         fTableCursor.addSelectionListener(fCursorSelectionListener);
193         fCursorEditor = new TableEditor (getTable());
194     }
195     
196     private void handleCursorKeyPressed(KeyEvent event)
197     {
198         if (event.character == '\r' && event.getSource() instanceof TableCursor)
199         {
200             activateCellEditor(null);
201             return;
202         }
203         
204         if (MemoryViewUtil.isValidEditEvent(event.keyCode))
205         {
206             // activate edit as soon as user types something at the cursor
207
if (event.getSource() instanceof TableCursor)
208             {
209                 int col = fTableCursor.getColumn();
210                 if (getCellEditors()[col] instanceof TextCellEditor)
211                 {
212                     String JavaDoc initialValue = String.valueOf(event.character);
213                     activateCellEditor(initialValue);
214                 }
215             }
216         }
217     }
218     
219     private void handleCursorMouseEvent(MouseEvent e){
220         if (e.button == 1)
221         {
222             int col = fTableCursor.getColumn();
223             if (col > 0 && col <= (getNumCol()))
224                 activateCellEditor(null);
225         }
226     }
227     
228     private void handleCursorTraverseEvt(TraverseEvent e){
229         if (fTableCursor.getRow() == null)
230             return;
231         
232         Table table = (Table)fTableCursor.getParent();
233         int row = table.indexOf(fTableCursor.getRow());
234         int col = fTableCursor.getColumn();
235         if (col == getNumCol() && e.keyCode == SWT.ARROW_RIGHT)
236         {
237             if (row + 1>= table.getItemCount())
238             {
239                 return;
240             }
241             
242             row = row +1;
243             col = 0;
244             fTableCursor.setSelection(row, col);
245         }
246         if (col <= 1 && e.keyCode == SWT.ARROW_LEFT)
247         {
248             if (row-1 < 0)
249             {
250                 return;
251             }
252             
253             row = row - 1;
254             col = getNumCol()+1;
255             fTableCursor.setSelection(row, col);
256         }
257         
258         handleCursorMoved();
259     }
260     
261     /**
262      * Update selected address.
263      * Load more memory if required.
264      */

265     private void handleCursorMoved()
266     {
267         fSelectionKey = getSelectionKeyFromCursor();
268         fPendingSelection = null;
269         
270         if (AsyncVirtualContentTableViewer.DEBUG_DYNAMIC_LOADING)
271             System.out.println(Thread.currentThread().getName() + " cursor moved selection is: " + ((BigInteger JavaDoc)fSelectionKey).toString(16)); //$NON-NLS-1$
272

273         // now check to see if the cursor is approaching buffer limit
274
handleScrollBarSelection();
275         fireSelectionChanged(fSelectionKey);
276     }
277     
278     private int getNumCol() {
279         
280         int bytesPerLine = fRendering.getBytesPerLine();
281         int columnSize = fRendering.getBytesPerColumn();
282         
283         return bytesPerLine/columnSize;
284     }
285     
286     /**
287      * Sets the cursor at the specified address
288      * @param key selection key
289      */

290     public void setSelection(Object JavaDoc key)
291     {
292         fPendingSelection = key;
293         attemptSetKeySelection();
294     }
295     
296     public Object JavaDoc getSelectionKey()
297     {
298         return fSelectionKey;
299     }
300     
301     private synchronized void attemptSetKeySelection()
302     {
303         if (fPendingSelection != null) {
304             doAttemptSetKeySelection(fPendingSelection);
305         }
306         
307     }
308     
309     synchronized private Object JavaDoc doAttemptSetKeySelection(final Object JavaDoc key)
310     {
311         if (getBufferTopKey() == null || getBufferEndKey() == null)
312             return key;
313         
314         // calculate selected row address
315
int[] location = getCoordinatesFromKey(key);
316         if(location.length == 0)
317         {
318             return key;
319         }
320         
321         UIJob uiJob = new UIJob("Set Cursor Selection"){ //$NON-NLS-1$
322

323             public IStatus runInUIThread(IProgressMonitor monitor) {
324                 try {
325                     if (AsyncVirtualContentTableViewer.DEBUG_DYNAMIC_LOADING)
326                         System.out.println(getRendering() + " set cursor selection " + ((BigInteger JavaDoc)key).toString(16)); //$NON-NLS-1$
327

328                     if (fPendingSelection != null && fPendingSelection != key)
329                         return Status.OK_STATUS;
330                     
331                     if (fTableCursor.isDisposed())
332                         return Status.OK_STATUS;
333                     
334                     // by the time this is called, the location may not be valid anymore
335
int[] newLocation = getCoordinatesFromKey(key);
336                     if (newLocation.length == 0)
337                     {
338                         Object JavaDoc selectionKey = getSelectionKey();
339                         fPendingSelection = selectionKey;
340                         return Status.OK_STATUS;
341                     }
342                     
343                     fSelectionKey = key;
344                     fPendingSelection = null;
345                     
346                     if (AsyncVirtualContentTableViewer.DEBUG_DYNAMIC_LOADING)
347                     {
348                         System.out.println(getRendering() + " set cursor selection, row is " + getTable().getItem(newLocation[0]).getData()); //$NON-NLS-1$
349
System.out.println(getRendering() + " set cursor selection, model is " + getVirtualContentModel().getElement(newLocation[0])); //$NON-NLS-1$
350
}
351                     
352                     fTableCursor.setSelection(newLocation[0], newLocation[1]);
353                     showTableCursor(true);
354                     
355                     int topIndex = getTable().getTopIndex();
356                     Object JavaDoc topKey = getVirtualContentModel().getKey(topIndex);
357                     setTopIndexKey(topKey);
358                     
359                     
360                 } catch (RuntimeException JavaDoc e) {
361                     
362                     // by the time this is called, the selection may no longer
363
// get the latest selection and try to set selection again
364
Object JavaDoc selectionKey = getSelectionKey();
365                     fPendingSelection = selectionKey;
366                     doAttemptSetKeySelection(selectionKey);
367                 }
368                 return Status.OK_STATUS;
369             }};
370             
371         uiJob.setSystem(true);
372         uiJob.schedule();
373         
374         return null;
375     }
376     
377     /**
378      *
379      * @param key
380      * @return the coordinates of the key
381      * Element[0] is the row index
382      * Element[1] is the column index
383      */

384     private int[] getCoordinatesFromKey(Object JavaDoc key)
385     {
386         final int row = indexOf(key);
387         
388         if (row == -1)
389         {
390             return new int[0];
391         }
392         
393         Object JavaDoc element = getVirtualContentModel().getElement(row);
394         final int col = columnOf(element, key);
395         
396         if (col == -1)
397         {
398             return new int[0];
399         }
400         return new int[]{row, col};
401     }
402     
403     private Object JavaDoc getSelectionKeyFromCursor()
404     {
405         int idx = getTable().indexOf(fTableCursor.getRow());
406         int col = fTableCursor.getColumn();
407         
408         return getVirtualContentModel().getKey(idx, col);
409     }
410     
411     private Object JavaDoc getBufferTopKey()
412     {
413         return getKey(0);
414     }
415     
416     private Object JavaDoc getBufferEndKey()
417     {
418         AbstractVirtualContentTableModel model = getVirtualContentModel();
419         
420         if (model != null)
421             return getKey(model.getElements().length-1);
422         return null;
423     }
424     
425     public int indexOf(Object JavaDoc key)
426     {
427         int idx = -1;
428         AbstractVirtualContentTableModel model = getVirtualContentModel();
429         if (model != null)
430             idx = model.indexOfKey(key);
431         return idx;
432     }
433     
434     private int columnOf(Object JavaDoc element, Object JavaDoc key)
435     {
436         int idx = -1;
437         AbstractVirtualContentTableModel model = getVirtualContentModel();
438         if (model != null)
439         {
440             idx = model.columnOf(element, key);
441         }
442         return idx;
443     }
444     
445     public Object JavaDoc getKey(int index)
446     {
447         AbstractVirtualContentTableModel model = getVirtualContentModel();
448         if (model != null)
449         {
450             Object JavaDoc key = model.getKey(index);
451             return key;
452         }
453         return null;
454     }
455     
456     public Object JavaDoc getKey(int row, int col)
457     {
458         AbstractVirtualContentTableModel model = getVirtualContentModel();
459         if (model != null)
460             return model.getKey(row, col);
461         return null;
462     }
463     
464     
465     protected synchronized void preservingSelection(Runnable JavaDoc updateCode) {
466         Object JavaDoc oldTopIndexKey = null;
467         
468         if (getPendingSetTopIndexKey() == null) {
469             // preserve selection
470
oldTopIndexKey = getTopIndexKey();
471         }
472         else
473         {
474             oldTopIndexKey = getPendingSetTopIndexKey();
475         }
476         Object JavaDoc oldSelectionKey = null;
477         try {
478             if (AsyncVirtualContentTableViewer.DEBUG_DYNAMIC_LOADING)
479             {
480                 if (oldTopIndexKey != null)
481                     System.out.println(getRendering() + " preserve top index: " + ((BigInteger JavaDoc)oldTopIndexKey).toString(16)); //$NON-NLS-1$
482
else
483                     System.out.println("top index key is null, nothing to preserve"); //$NON-NLS-1$
484
}
485
486             if (fPendingSelection != null)
487                 oldSelectionKey = fPendingSelection;
488             else
489                 oldSelectionKey = getSelectionKey();
490             
491             if (AsyncVirtualContentTableViewer.DEBUG_DYNAMIC_LOADING)
492             {
493                 if (oldTopIndexKey != null)
494                     System.out.println(getRendering() + " preserve selection: " + ((BigInteger JavaDoc)oldSelectionKey).toString(16)); //$NON-NLS-1$
495
else
496                     System.out.println("selection key is null, nothing to preserve"); //$NON-NLS-1$
497
}
498             
499             // perform the update
500
updateCode.run();
501             
502         } finally {
503             
504             if (oldSelectionKey != null)
505             {
506                 if (AsyncVirtualContentTableViewer.DEBUG_DYNAMIC_LOADING)
507                     System.out.println(getRendering() + " preserved selection " + ((BigInteger JavaDoc)oldSelectionKey).toString(16)); //$NON-NLS-1$
508
setSelection(oldSelectionKey);
509             }
510             
511             if (getPendingSetTopIndexKey() != null)
512             {
513                 if (AsyncVirtualContentTableViewer.DEBUG_DYNAMIC_LOADING)
514                     System.out.println(getRendering() + " finished top index: " + ((BigInteger JavaDoc)oldTopIndexKey).toString(16)); //$NON-NLS-1$
515
setTopIndex(getPendingSetTopIndexKey());
516             }
517             else if (oldTopIndexKey != null)
518             {
519                 setTopIndex(oldTopIndexKey);
520                 
521                 if (AsyncVirtualContentTableViewer.DEBUG_DYNAMIC_LOADING)
522                     System.out.println(getRendering() + " finished top index: " + ((BigInteger JavaDoc)oldTopIndexKey).toString(16)); //$NON-NLS-1$
523
}
524         }
525     }
526     
527     public void dispose()
528     {
529         super.dispose();
530         
531         if (fTableCursor != null && !fTableCursor.isDisposed())
532         {
533             fCursorEditor.dispose();
534             fCursorEditor = null;
535             
536             fTableCursor.removeTraverseListener(fCursorTraverseListener);
537             fTableCursor.removeKeyListener(fCursorKeyAdapter);
538             fTableCursor.removeMouseListener(fCursorMouseListener);
539             fTableCursor.removeSelectionListener(fCursorSelectionListener);
540             
541             fTableCursor.dispose();
542             fTableCursor = null;
543         }
544     }
545     
546     public void showTableCursor(final boolean show)
547     {
548         
549         Display display = DebugUIPlugin.getDefault().getWorkbench().getDisplay();
550         if (Thread.currentThread() == display.getThread())
551         {
552             if (!fTableCursor.isDisposed())
553             {
554                 if (fTableCursor.isVisible() != show)
555                     fTableCursor.setVisible(show);
556             }
557         }
558         else
559         {
560             UIJob job = new UIJob("show table cursor"){ //$NON-NLS-1$
561

562                 public IStatus runInUIThread(IProgressMonitor monitor) {
563                     if (!fTableCursor.isDisposed())
564                     {
565                         if (fTableCursor.isVisible() != show)
566                             fTableCursor.setVisible(show);
567                     }
568                     return Status.OK_STATUS;
569                 }};
570                 
571             job.setSystem(true);
572             job.schedule();
573         }
574     }
575
576     private void handleTableMouseEvent(MouseEvent e) {
577         // figure out new cursor position based on here the mouse is pointing
578
TableItem[] tableItems = getTable().getItems();
579         TableItem selectedRow = null;
580         int colNum = -1;
581         int numCol = getColumnProperties().length;
582         
583         for (int j=0; j<tableItems.length; j++)
584         {
585             TableItem item = tableItems[j];
586             if (item.getData() != null)
587             {
588                 for (int i=0; i<numCol; i++)
589                 {
590                     Rectangle bound = item.getBounds(i);
591                     if (bound.contains(e.x, e.y))
592                     {
593                         colNum = i;
594                         selectedRow = item;
595                         break;
596                     }
597                 }
598             }
599             if (colNum >= 0)
600                 break;
601         }
602         
603         // if column position cannot be determined, return
604
if (colNum < 1)
605             return;
606         
607         // handle user mouse click onto table
608
// move cursor to new position
609
if (selectedRow != null)
610         {
611             int row = getTable().indexOf(selectedRow);
612             showTableCursor(true);
613             fTableCursor.setSelection(row, colNum);
614             
615             // manually call this since we don't get an event when
616
// the table cursor changes selection.
617
handleCursorMoved();
618             
619             fTableCursor.setFocus();
620         }
621     }
622
623     /**
624      * Activate cell editor and prefill it with initial value.
625      * If initialValue is null, use cell content as initial value
626      * @param initialValue
627      */

628     private void activateCellEditor(String JavaDoc initialValue) {
629
630         final int col = fTableCursor.getColumn();
631         final int row = indexOf(fSelectionKey);
632
633         if (row < 0)
634             return;
635
636         // do not allow user to edit address column
637
if (col == 0 || col > getNumCol()) {
638             return;
639         }
640
641         ICellModifier cellModifier = null;
642
643         cellModifier = getCellModifier();
644
645         TableItem tableItem = getTable().getItem(row);
646
647         Object JavaDoc element = tableItem.getData();
648
649         if (element != null) {
650             Object JavaDoc property = getColumnProperties()[col];
651             Object JavaDoc value = cellModifier.getValue(element, (String JavaDoc) property);
652             boolean canEdit = cellModifier
653                     .canModify(element, (String JavaDoc) property);
654
655             if (!canEdit)
656                 return;
657
658             CellEditor editor = getCellEditors()[col];
659             if (editor != null) {
660                 // The control that will be the editor must be a child of the
661
// Table
662
Control control = editor.getControl();
663
664                 Object JavaDoc cellValue = null;
665
666                 if (initialValue != null) {
667                     cellValue = initialValue;
668                 } else {
669                     cellValue = value;
670                 }
671
672                 editor.setValue(cellValue);
673
674                 fCursorEditor.horizontalAlignment = SWT.LEFT;
675                 fCursorEditor.grabHorizontal = true;
676
677                 // Open the editor editor in selected column of the selected
678
// row.
679
fCursorEditor.setEditor(control, tableItem, col);
680
681                 // Assign focus to the editor control
682
editor.setFocus();
683
684                 if (initialValue != null && control instanceof Text) {
685                     ((Text) control).clearSelection();
686                 }
687
688                 control.setFont(JFaceResources
689                         .getFont(IInternalDebugUIConstants.FONT_NAME));
690
691                 // add listeners for the editor control
692
addListeners(control);
693                 
694                 fCellEditorListener = new CellEditorListener(row, col, editor);
695                 editor.addListener(fCellEditorListener);
696
697                 // move cursor below editor control
698
fTableCursor.moveBelow(control);
699             }
700         }
701     }
702     
703     private void deactivateEditor(CellEditor editor)
704     {
705         removeListeners(editor.getControl());
706         fTableCursor.moveAbove(editor.getControl());
707         fTableCursor.setFocus();
708     }
709     
710     /*
711      * @param editor
712      */

713     private void addListeners(Control control) {
714         
715         fEditorKeyListener = new KeyAdapter() {
716             public void keyPressed(KeyEvent e) {
717                 handleKeyEventInEditor(e);
718             }
719         };
720
721         control.addKeyListener(fEditorKeyListener);
722     }
723     
724     /**
725      * @param event
726      */

727     private void handleKeyEventInEditor(KeyEvent event) {
728         
729         final KeyEvent e = event;
730         Display.getDefault().asyncExec(new Runnable JavaDoc()
731         {
732             public void run()
733             {
734                 Object JavaDoc obj = e.getSource();
735                 if (obj instanceof Control)
736                 {
737                     Control control = (Control)obj;
738                     int row = fCellEditorListener.getRow();
739                     int col = fCellEditorListener.getCol();
740                     
741                     try
742                     {
743                         switch (e.keyCode)
744                         {
745                             case 0:
746                                 doHandleKeyEvent(row, col);
747                                 break;
748                             case SWT.ESC:
749                                 cancelEditing(row, col);
750                                 break;
751                             default :
752                                 doHandleKeyEvent(row, col);
753                             break;
754                         }
755                     }
756                     catch (NumberFormatException JavaDoc e1)
757                     {
758                         MemoryViewUtil.openError(DebugUIMessages.MemoryViewCellModifier_failure_title,
759                             DebugUIMessages.MemoryViewCellModifier_data_is_invalid, null);
760                         
761                         fTableCursor.setSelection(row, col);
762                         handleCursorMoved();
763                 
764                         removeListeners(control);
765                     }
766                 }
767             }
768         });
769     }
770     
771     private void doHandleKeyEvent(int row, int col)
772     {
773         int numCharsPerByte = fRendering.getNumCharsPerByte();
774         if (numCharsPerByte > 0)
775         {
776             Object JavaDoc value = getCellEditors()[col].getValue();
777             if (getCellEditors()[col] instanceof TextCellEditor && value instanceof String JavaDoc)
778             {
779                 String JavaDoc str = (String JavaDoc)value;
780                 
781                 if (str.length() > fRendering.getBytesPerColumn()*numCharsPerByte)
782                 {
783                     String JavaDoc newValue = str;
784                     
785                     CellEditor editor = getCellEditors()[col];
786                     editor.setValue(newValue.substring(0,fRendering.getBytesPerColumn()* numCharsPerByte));
787                     
788                     // We want to call modify value here to avoid race condition.
789
// Relying on the editor event to modify the cell may introduce a race condition since
790
// we try to activate another cell editor in this method. If we happen to use same cell
791
// editor in the next activation, the value of the editor may be incorrect when the listener gets the event.
792
// We may write the wrong value in that case. Calling modify here allows us to capture the value
793
// now and send that to the model.
794
fCellEditorListener.cancelEditor();
795                     deactivateEditor(editor);
796                     modifyValue(fCellEditorListener.getRow(), fCellEditorListener.getCol(), editor.getValue());
797                     
798                     // if cursor is at the end of a line, move to next line
799
if (col >= getNumCol())
800                     {
801                         col = 1;
802                         row++;
803                     }
804                     else
805                     {
806                         col++;
807                     }
808                     
809                     fTableCursor.setSelection(row, col);
810                     handleCursorMoved();
811                                                         
812                     activateCellEditor(newValue.substring(fRendering.getBytesPerColumn()*numCharsPerByte));
813                 }
814             }
815         }
816     }
817     
818     private void cancelEditing(int row, int col)
819     {
820         // if user has pressed escape, do not commit the changes
821
// remove listener to avoid getting notified on the modify value
822
fCellEditorListener.cancelEditor();
823         deactivateEditor(getCellEditors()[col]);
824         
825         fTableCursor.setSelection(row, col);
826         handleCursorMoved();
827         
828         // cursor needs to have focus to remove focus from cell editor
829
fTableCursor.setFocus();
830     }
831     
832     /**
833      * @param control
834      */

835     private void removeListeners(Control control) {
836         
837         control.removeKeyListener(fEditorKeyListener);
838     }
839     
840     /**
841      * Modify value and send new value to debug adapter
842      * @param row
843      * @param col
844      * @param newValue
845      * @throws NumberFormatException
846      */

847     private void modifyValue(int row, int col, Object JavaDoc newValue) throws NumberFormatException JavaDoc
848     {
849         if (newValue instanceof String JavaDoc && ((String JavaDoc)newValue).length() == 0)
850         {
851             // do not do anything if user has not entered anything
852
return;
853         }
854         
855         if (row >= 0 && row < getTable().getItemCount())
856         {
857             TableItem tableItem = getTable().getItem(row);
858     
859             Object JavaDoc property = getColumnProperties()[col];
860             getCellModifier().modify(tableItem, (String JavaDoc)property, newValue);
861         }
862     }
863     
864     public TableCursor getCursor()
865     {
866         return fTableCursor;
867     }
868     
869     /* (non-Javadoc)
870      * @see org.eclipse.jface.viewers.ContentViewer#getLabelProvider()
871      * Implemented minimum to work with PrintTableRendering action.
872      * This is not a real table labe provider, only goes to the table
873      * to get the text at the specified row and column.
874      */

875     public IBaseLabelProvider getLabelProvider() {
876         return new ITableLabelProvider() {
877
878             public Image getColumnImage(Object JavaDoc element, int columnIndex) {
879                 return null;
880             }
881
882             public String JavaDoc getColumnText(Object JavaDoc element, int columnIndex) {
883                 int idx = getVirtualContentModel().indexOfElement(element);
884                 if (idx >= 0 )
885                 {
886                     TableItem item = getTable().getItem(idx);
887                     return item.getText(columnIndex);
888                 }
889                 return ""; //$NON-NLS-1$
890
}
891
892             public void addListener(ILabelProviderListener listener) {
893             }
894
895             public void dispose() {
896             }
897
898             public boolean isLabelProperty(Object JavaDoc element, String JavaDoc property) {
899                 return false;
900             }
901
902             public void removeListener(ILabelProviderListener listener) {
903             }};
904     }
905     
906     public void formatViewer()
907     {
908         if (getModel() == null || !hasPendingUpdates())
909             doFormatViewer();
910         else
911             // do not format in the middle of an update
912
// set pending update and will format when update is completed
913
fPendingFormatViewer = true;
914     }
915
916     /**
917      *
918      */

919     private void doFormatViewer() {
920         fPendingFormatViewer = false;
921         preservingSelection(new Runnable JavaDoc() {
922
923             public void run() {
924                 // causes the content of the table viewer to be replaced
925
// without asking content adapter for content
926
AbstractVirtualContentTableModel model = getVirtualContentModel();
927                 if (model != null)
928                 {
929                     model.handleViewerChanged();
930                 }
931             }});
932     }
933     
934     private void fireSelectionChanged(Object JavaDoc selectionKey)
935     {
936         if (selectionKey != null)
937         {
938             SelectionChangedEvent evt = new SelectionChangedEvent(this, new StructuredSelection(selectionKey));
939             fireSelectionChanged(evt);
940         }
941     }
942
943     public void handlePresentationFailure(IStatusMonitor monitor, IStatus status) {
944         super.handlePresentationFailure(monitor, status);
945     }
946     
947     public void refresh(boolean getContent)
948     {
949         if (getContent)
950             refresh();
951         else
952         {
953             preservingSelection(new Runnable JavaDoc() {
954
955                 public void run() {
956                     AbstractVirtualContentTableModel model = getVirtualContentModel();
957                     if (model != null)
958                     {
959                         Object JavaDoc[] elements = model.getElements();
960                         model.remove(elements);
961                         model.add(elements);
962                     }
963                 }});
964         }
965     }
966     
967     protected void tableTopIndexSetComplete() {
968         
969         if (!fTableCursor.isDisposed())
970         {
971             // TODO: work around swt bug, must force a table cursor redraw after top index is changed
972
// BUG 130130
973
int[] coordinates = getCoordinatesFromKey(getSelectionKey());
974             if (coordinates.length > 0)
975                 fTableCursor.setVisible(true);
976             else
977                 fTableCursor.setVisible(false);
978         }
979     }
980
981     /* (non-Javadoc)
982      * @see org.eclipse.debug.internal.ui.viewers.model.provisional.viewers.AsynchronousViewer#getModel()
983      */

984     public AsynchronousModel getModel() {
985         return super.getModel();
986     }
987     
988     // TODO: need pluggable model to be truly flexible
989
protected AbstractVirtualContentTableModel createVirtualContentTableModel() {
990         return new TableRenderingModel(this);
991     }
992
993     protected void updateComplete(IStatusMonitor monitor) {
994         super.updateComplete(monitor);
995         
996         if (!hasPendingUpdates() && !fTableCursor.isDisposed())
997         {
998             attemptSetKeySelection();
999             fTableCursor.redraw();
1000            
1001            // if the viewer has pending top index, then more updates will come in
1002
// and the cursor should not be redrawn yet.
1003
if (!hasPendingSetTopIndex())
1004            {
1005                preservingSelection(new Runnable JavaDoc() {
1006
1007                    public void run() {
1008
1009                        int[] coordinates = getCoordinatesFromKey(getSelectionKey());
1010                        if (coordinates.length > 0)
1011                            fTableCursor.setVisible(true);
1012                        else
1013                            fTableCursor.setVisible(false);
1014                    }});
1015            }
1016        }
1017        
1018        if (!hasPendingUpdates() && fPendingFormatViewer)
1019        {
1020            formatViewer();
1021            resizeColumnsToPreferredSize();
1022        }
1023    }
1024
1025    protected void clear(Widget item) {
1026        super.clear(item);
1027        
1028        // this table viewer assumes that #getData will return null
1029
// set data to null when clearing an item.
1030
// only visible item will get SET DATA event again and at that time
1031
// the viewer would set the data back.
1032
if (item instanceof TableItem)
1033        {
1034            item.setData(null);
1035        }
1036    }
1037}
1038
Popular Tags