KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > debug > internal > ui > memory > provisional > AbstractAsyncTableRendering


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.memory.provisional;
13
14
15 import java.math.BigInteger JavaDoc;
16 import java.util.ArrayList JavaDoc;
17 import java.util.Iterator JavaDoc;
18
19 import org.eclipse.core.commands.AbstractHandler;
20 import org.eclipse.core.commands.Command;
21 import org.eclipse.core.commands.ExecutionEvent;
22 import org.eclipse.core.commands.ExecutionException;
23 import org.eclipse.core.runtime.CoreException;
24 import org.eclipse.core.runtime.IProgressMonitor;
25 import org.eclipse.core.runtime.IStatus;
26 import org.eclipse.core.runtime.Status;
27 import org.eclipse.core.runtime.jobs.ISchedulingRule;
28 import org.eclipse.core.runtime.jobs.Job;
29 import org.eclipse.debug.core.DebugException;
30 import org.eclipse.debug.core.model.IMemoryBlock;
31 import org.eclipse.debug.core.model.IMemoryBlockExtension;
32 import org.eclipse.debug.core.model.MemoryByte;
33 import org.eclipse.debug.internal.ui.DebugUIMessages;
34 import org.eclipse.debug.internal.ui.DebugUIPlugin;
35 import org.eclipse.debug.internal.ui.IInternalDebugUIConstants;
36 import org.eclipse.debug.internal.ui.memory.IPersistableDebugElement;
37 import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants;
38 import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelChangedListener;
39 import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta;
40 import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxy;
41 import org.eclipse.debug.internal.ui.viewers.model.provisional.IStatusMonitor;
42 import org.eclipse.debug.internal.ui.views.memory.MemoryViewUtil;
43 import org.eclipse.debug.internal.ui.views.memory.renderings.AbstractBaseTableRendering;
44 import org.eclipse.debug.internal.ui.views.memory.renderings.AbstractVirtualContentTableModel;
45 import org.eclipse.debug.internal.ui.views.memory.renderings.AsyncCopyTableRenderingAction;
46 import org.eclipse.debug.internal.ui.views.memory.renderings.AsyncPrintTableRenderingAction;
47 import org.eclipse.debug.internal.ui.views.memory.renderings.AsyncTableRenderingCellModifier;
48 import org.eclipse.debug.internal.ui.views.memory.renderings.AsyncTableRenderingViewer;
49 import org.eclipse.debug.internal.ui.views.memory.renderings.AsyncVirtualContentTableViewer;
50 import org.eclipse.debug.internal.ui.views.memory.renderings.CopyTableRenderingToClipboardAction;
51 import org.eclipse.debug.internal.ui.views.memory.renderings.FormatTableRenderingAction;
52 import org.eclipse.debug.internal.ui.views.memory.renderings.FormatTableRenderingDialog;
53 import org.eclipse.debug.internal.ui.views.memory.renderings.GoToAddressAction;
54 import org.eclipse.debug.internal.ui.views.memory.renderings.GoToAddressComposite;
55 import org.eclipse.debug.internal.ui.views.memory.renderings.IPresentationErrorListener;
56 import org.eclipse.debug.internal.ui.views.memory.renderings.IVirtualContentListener;
57 import org.eclipse.debug.internal.ui.views.memory.renderings.MemorySegment;
58 import org.eclipse.debug.internal.ui.views.memory.renderings.PendingPropertyChanges;
59 import org.eclipse.debug.internal.ui.views.memory.renderings.PrintTableRenderingAction;
60 import org.eclipse.debug.internal.ui.views.memory.renderings.ReformatAction;
61 import org.eclipse.debug.internal.ui.views.memory.renderings.ResetToBaseAddressAction;
62 import org.eclipse.debug.internal.ui.views.memory.renderings.TableRenderingContentDescriptor;
63 import org.eclipse.debug.internal.ui.views.memory.renderings.TableRenderingLine;
64 import org.eclipse.debug.ui.DebugUITools;
65 import org.eclipse.debug.ui.IDebugUIConstants;
66 import org.eclipse.debug.ui.memory.AbstractTableRendering;
67 import org.eclipse.debug.ui.memory.IMemoryBlockTablePresentation;
68 import org.eclipse.debug.ui.memory.IMemoryRendering;
69 import org.eclipse.debug.ui.memory.IMemoryRenderingContainer;
70 import org.eclipse.debug.ui.memory.IMemoryRenderingSite;
71 import org.eclipse.debug.ui.memory.IMemoryRenderingSynchronizationService;
72 import org.eclipse.debug.ui.memory.IMemoryRenderingType;
73 import org.eclipse.debug.ui.memory.IResettableMemoryRendering;
74 import org.eclipse.jface.action.Action;
75 import org.eclipse.jface.action.IMenuListener;
76 import org.eclipse.jface.action.IMenuManager;
77 import org.eclipse.jface.action.MenuManager;
78 import org.eclipse.jface.action.Separator;
79 import org.eclipse.jface.dialogs.IDialogConstants;
80 import org.eclipse.jface.preference.IPreferenceStore;
81 import org.eclipse.jface.resource.ImageDescriptor;
82 import org.eclipse.jface.resource.JFaceResources;
83 import org.eclipse.jface.text.Document;
84 import org.eclipse.jface.text.TextViewer;
85 import org.eclipse.jface.util.IPropertyChangeListener;
86 import org.eclipse.jface.util.PropertyChangeEvent;
87 import org.eclipse.jface.viewers.CellEditor;
88 import org.eclipse.jface.viewers.IBasicPropertyConstants;
89 import org.eclipse.jface.viewers.ICellModifier;
90 import org.eclipse.jface.viewers.IColorProvider;
91 import org.eclipse.jface.viewers.IFontProvider;
92 import org.eclipse.jface.viewers.ILabelProvider;
93 import org.eclipse.jface.viewers.ISelectionChangedListener;
94 import org.eclipse.jface.viewers.ISelectionProvider;
95 import org.eclipse.jface.viewers.SelectionChangedEvent;
96 import org.eclipse.jface.viewers.StructuredViewer;
97 import org.eclipse.jface.viewers.TextCellEditor;
98 import org.eclipse.swt.SWT;
99 import org.eclipse.swt.custom.SashForm;
100 import org.eclipse.swt.custom.StyledText;
101 import org.eclipse.swt.events.ControlEvent;
102 import org.eclipse.swt.events.ControlListener;
103 import org.eclipse.swt.events.KeyAdapter;
104 import org.eclipse.swt.events.KeyEvent;
105 import org.eclipse.swt.events.MouseEvent;
106 import org.eclipse.swt.events.MouseTrackAdapter;
107 import org.eclipse.swt.events.PaintEvent;
108 import org.eclipse.swt.events.PaintListener;
109 import org.eclipse.swt.events.SelectionAdapter;
110 import org.eclipse.swt.events.SelectionEvent;
111 import org.eclipse.swt.graphics.Font;
112 import org.eclipse.swt.graphics.Point;
113 import org.eclipse.swt.graphics.Rectangle;
114 import org.eclipse.swt.layout.GridData;
115 import org.eclipse.swt.layout.GridLayout;
116 import org.eclipse.swt.widgets.Button;
117 import org.eclipse.swt.widgets.Composite;
118 import org.eclipse.swt.widgets.Control;
119 import org.eclipse.swt.widgets.Display;
120 import org.eclipse.swt.widgets.Event;
121 import org.eclipse.swt.widgets.Label;
122 import org.eclipse.swt.widgets.Listener;
123 import org.eclipse.swt.widgets.Menu;
124 import org.eclipse.swt.widgets.Shell;
125 import org.eclipse.swt.widgets.Table;
126 import org.eclipse.swt.widgets.TableColumn;
127 import org.eclipse.swt.widgets.TableItem;
128 import org.eclipse.swt.widgets.Text;
129 import org.eclipse.ui.IWorkbench;
130 import org.eclipse.ui.IWorkbenchActionConstants;
131 import org.eclipse.ui.PlatformUI;
132 import org.eclipse.ui.commands.ICommandService;
133 import org.eclipse.ui.contexts.IContextService;
134 import org.eclipse.ui.dialogs.PropertyDialogAction;
135 import org.eclipse.ui.model.IWorkbenchAdapter;
136 import org.eclipse.ui.part.PageBook;
137 import org.eclipse.ui.progress.UIJob;
138
139 /**
140  * Abstract implementation of a table rendering.
141  * <p>
142  * Clients should subclass from this class if they wish to provide a
143  * table rendering.
144  * </p>
145  * <p>
146  *
147  * The label of the rendering is constructed by retrieving the expression from
148  * <code>IMemoryBlockExtension</code>. For IMemoryBlock, the label is constructed
149  * using the memory block's start address.
150  *
151  * This rendering manages the change states of its memory bytes if the memory
152  * block does not opt to manage the change states. For IMemoryBlockExtension, if
153  * the memory block returns false when #supportsChangeManagement() is called, this
154  * rendering will calculate the change state for each byte when its content is updated.
155  * Clients may manages the change states of its memory block by returning true when
156  * #supportsChangeManagement() is called. This will cause this rendering to stop
157  * calculating the change states of the memory block. Instead it would rely on the
158  * attributes returned in the MemoryByte array to determine if a byte has changed.
159  * For IMemoryBlock, this rendering will manage the change states its content.
160  *
161  * When firing change event, be aware of the following:
162  * - whenever a change event is fired, the content provider for Memory View
163  * view checks to see if memory has actually changed.
164  * - If memory has actually changed, a refresh will commence. Changes to the memory block
165  * will be computed and will be shown with the delta icons.
166  * - If memory has not changed, content will not be refreshed. However, previous delta information
167  * will be erased. The screen will be refreshed to show that no memory has been changed. (All
168  * delta icons will be removed.)
169  *
170  * Please note that these APIs will be called multiple times by the Memory View.
171  * To improve performance, debug adapters need to cache the content of its memory block and only
172  * retrieve updated data when necessary.
173  * </p>
174
175  * @since 3.2
176  */

177 public abstract class AbstractAsyncTableRendering extends AbstractBaseTableRendering implements IPropertyChangeListener, IResettableMemoryRendering {
178
179     /**
180      * Property identifier for the selected address in a table rendering
181      * This property is used for synchronization between renderings.
182      */

183     public static final String JavaDoc PROPERTY_SELECTED_ADDRESS = AbstractTableRendering.PROPERTY_SELECTED_ADDRESS;
184     
185     /**
186      * Property identifier for the column size in a table rendering
187      * This property is used for synchronization between renderings.
188      */

189     public static final String JavaDoc PROPERTY_COL_SIZE = AbstractTableRendering.PROPERTY_COL_SIZE;
190     
191     /**
192      * Property identifier for the top row address in a table rendering.
193      * This property is used for synchronization between renderings.
194      */

195     public static final String JavaDoc PROPERTY_TOP_ADDRESS = AbstractTableRendering.PROPERTY_TOP_ADDRESS;
196     
197     private static final String JavaDoc ID_ASYNC_TABLE_RENDERING_CONTEXT = "org.eclipse.debug.ui.memory.abstractasynctablerendering"; //$NON-NLS-1$
198
private static final String JavaDoc ID_GO_TO_ADDRESS_COMMAND = "org.eclipse.debug.ui.command.gotoaddress"; //$NON-NLS-1$
199
private static final String JavaDoc ID_NEXT_PAGE_COMMAND = "org.eclipse.debug.ui.command.nextpage"; //$NON-NLS-1$
200
private static final String JavaDoc ID_PREV_PAGE_COMMAND = "org.eclipse.debug.ui.command.prevpage"; //$NON-NLS-1$
201

202     /**
203      * Property identifier for the row size in a table rendering
204      * This property is used for synchronization between renderings.
205      */

206     public static final String JavaDoc PROPERTY_ROW_SIZE = AbstractTableRendering.PROPERTY_ROW_SIZE;
207
208     private static final int DEFAULT_BUFFER_THRESHOLD = 1;
209     
210     private boolean fActivated = false;
211     
212 // TODO: review use of MemorySegment, need to be careful to ensure flexible hierarchy
213

214     private class ToggleAddressColumnAction extends Action {
215
216         public ToggleAddressColumnAction() {
217             super();
218             PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IDebugUIConstants.PLUGIN_ID
219                     + ".ShowAddressColumnAction_context"); //$NON-NLS-1$
220
updateActionLabel();
221         }
222
223         /*
224          * (non-Javadoc)
225          *
226          * @see org.eclipse.jface.action.IAction#run()
227          */

228         public void run() {
229             fIsShowAddressColumn = !fIsShowAddressColumn;
230             if (!fIsShowAddressColumn)
231             {
232                 fTableViewer.getTable().getColumn(0).setWidth(0);
233             }
234             else
235             {
236                 fTableViewer.getTable().getColumn(0).pack();
237             }
238             updateActionLabel();
239         }
240
241         /**
242          *
243          */

244         private void updateActionLabel() {
245             if (fIsShowAddressColumn) {
246                 setText(DebugUIMessages.ShowAddressColumnAction_0);
247             } else {
248                 setText(DebugUIMessages.ShowAddressColumnAction_1);
249             }
250         }
251     }
252     
253     private class NextPageAction extends Action
254     {
255         private NextPageAction()
256         {
257             super();
258             setText(DebugUIMessages.AbstractTableRendering_4);
259             PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IDebugUIConstants.PLUGIN_ID + ".NextPageAction_context"); //$NON-NLS-1$
260
}
261
262         public void run() {
263             BigInteger JavaDoc address = fContentDescriptor.getLoadAddress();
264             address = address.add(BigInteger.valueOf(getPageSizeInUnits()));
265             handlePageStartAddressChanged(address);
266         }
267     }
268     
269     private class PrevPageAction extends Action
270     {
271         private PrevPageAction()
272         {
273             super();
274             setText(DebugUIMessages.AbstractTableRendering_6);
275             PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IDebugUIConstants.PLUGIN_ID + ".PrevPageAction_context"); //$NON-NLS-1$
276
}
277
278         public void run() {
279             BigInteger JavaDoc address = fContentDescriptor.getLoadAddress();
280             address = address.subtract(BigInteger.valueOf(getPageSizeInUnits()));
281             handlePageStartAddressChanged(address);
282         }
283     }
284     
285     private class RenderingGoToAddressAction extends GoToAddressAction
286     {
287         public RenderingGoToAddressAction(AbstractBaseTableRendering rendering) {
288             super(rendering);
289         }
290         
291         public void run() {
292             showGoToAddressComposite();
293         }
294     }
295     
296     private class SwitchPageJob extends UIJob {
297         private Object JavaDoc fLock = new Object JavaDoc();
298         private boolean fShowMessagePage = false;
299         private String JavaDoc fMessage = ""; //$NON-NLS-1$
300

301         private SwitchPageJob() {
302             super("SwitchPageJob");//$NON-NLS-1$
303
setSystem(true);
304         }
305
306         private void setShowMessagePage(boolean showMsg) {
307             synchronized(fLock)
308             {
309                 fShowMessagePage = showMsg;
310             }
311         }
312
313         private void setMessage(String JavaDoc message) {
314             synchronized(fLock)
315             {
316                 fMessage = message;
317             }
318         }
319
320         public IStatus runInUIThread(IProgressMonitor monitor) {
321             
322             if (fPageBook.isDisposed())
323                 return Status.OK_STATUS;
324             
325             String JavaDoc msgToShow = null;
326             boolean showMsgPage = false;
327             synchronized (fLock) {
328                 msgToShow = fMessage;
329                 showMsgPage = fShowMessagePage;
330             }
331             
332             if (showMsgPage) {
333                 StyledText styleText = null;
334                 fShowMessage = true;
335
336                 styleText = fTextViewer.getTextWidget();
337
338                 if (styleText != null)
339                     styleText.setText(msgToShow);
340                 fPageBook.showPage(fTextViewer.getControl());
341             } else {
342                 fShowMessage = false;
343                 fPageBook.showPage(fTableViewer.getControl().getParent());
344             }
345             return Status.OK_STATUS;
346         }
347     }
348     
349     
350     private class SerialByObjectRule implements ISchedulingRule
351     {
352         private Object JavaDoc fObject = null;
353         
354         public SerialByObjectRule(Object JavaDoc lock) {
355             fObject = lock;
356         }
357
358         /* (non-Javadoc)
359          * @see org.eclipse.core.runtime.jobs.ISchedulingRule#contains(org.eclipse.core.runtime.jobs.ISchedulingRule)
360          */

361         public boolean contains(ISchedulingRule rule) {
362             return rule == this;
363         }
364
365         /* (non-Javadoc)
366          * @see org.eclipse.core.runtime.jobs.ISchedulingRule#isConflicting(org.eclipse.core.runtime.jobs.ISchedulingRule)
367          */

368         public boolean isConflicting(ISchedulingRule rule) {
369             if (rule instanceof SerialByObjectRule) {
370                 SerialByObjectRule rRule = (SerialByObjectRule) rule;
371                 return fObject == rRule.fObject;
372             }
373             return false;
374         }
375     }
376     
377     private PageBook fPageBook;
378     private AsyncTableRenderingViewer fTableViewer;
379     private TextViewer fTextViewer;
380     private Shell fToolTipShell;
381     private MemoryViewPresentationContext fPresentationContext;
382     private int fAddressableSize;
383     private TableRenderingContentDescriptor fContentDescriptor;
384     private int fBytePerLine;
385     private int fColumnSize;
386     private boolean fShowMessage = false;
387     private String JavaDoc fLabel;
388     private IWorkbenchAdapter fWorkbenchAdapter;
389     private int fPageSize;
390     private int fPreBufferSize = -1;
391     private int fPostBufferSize = -1;
392     private SashForm fSashForm;
393     private GoToAddressComposite fGoToAddressComposite;
394     
395     // actions
396
private GoToAddressAction fGoToAddressAction;
397     private PrintTableRenderingAction fPrintViewTabAction;
398     private CopyTableRenderingToClipboardAction fCopyToClipboardAction;
399     private FormatTableRenderingAction fFormatRenderingAction;
400     private ReformatAction fReformatAction;
401     private ToggleAddressColumnAction fToggleAddressColumnAction;
402     private ResetToBaseAddressAction fResetMemoryBlockAction;
403     private PropertyDialogAction fPropertiesDialogAction;
404     private NextPageAction fNextAction;
405     private PrevPageAction fPrevAction;
406     
407     private ArrayList JavaDoc fContext = new ArrayList JavaDoc();
408     private AbstractHandler fGoToAddressHandler;
409     
410     private AbstractHandler fNextPageHandler;
411     private AbstractHandler fPrevPageHandler;
412     
413     private boolean fIsCreated = false;
414     private boolean fIsDisposed = false;
415     private boolean fIsShowAddressColumn = true;
416     
417     private SwitchPageJob fSwitchPageJob = new SwitchPageJob();
418     private boolean fError = false;
419     
420     private PendingPropertyChanges fPendingSyncProperties;
421     
422     // list of menu listeners for popupMenuMgr.
423
private ArrayList JavaDoc fMenuListeners;
424     private MenuManager fMenuMgr;
425     
426     private ISchedulingRule serialByRenderingRule = new SerialByObjectRule(this);
427     
428     /**
429      * Identifier for an empty group preceding all context menu actions
430      * (value <code>"popUpBegin"</code>).
431      */

432     public static final String JavaDoc EMPTY_MEMORY_GROUP = "popUpBegin"; //$NON-NLS-1$
433

434     /**
435      * Identifier for an empty group following navigation actions in the rendering
436      * (value <code>navigationGroup</code>).
437      */

438     public static final String JavaDoc EMPTY_NAVIGATION_GROUP = "navigationGroup"; //$NON-NLS-1$
439

440     /**
441      * Identifier for an empty group following actions that are only applicable in
442      * non-auto loading mode
443      * (value <code>nonAutoLoadGroup</code>).
444      */

445     public static final String JavaDoc EMPTY_NON_AUTO_LOAD_GROUP = "nonAutoLoadGroup"; //$NON-NLS-1$
446

447     /**
448      * Identifier for an empty group following properties actions
449      * (value <code>propertyGroup</code>).
450      */

451     public static final String JavaDoc EMPTY_PROPERTY_GROUP = "propertyGroup"; //$NON-NLS-1$
452

453     private ISelectionChangedListener fViewerSelectionChangedListener = new ISelectionChangedListener() {
454         public void selectionChanged(SelectionChangedEvent event) {
455             updateSyncTopAddress(getTopVisibleAddress());
456             updateSyncSelectedAddress(getSelectedAddress());
457         }
458     };
459     
460     private SelectionAdapter fScrollBarSelectionListener = new SelectionAdapter() {
461         public void widgetSelected(SelectionEvent e) {
462             updateSyncTopAddress(getTopVisibleAddress());
463         }
464     };
465     
466     private IModelChangedListener fModelChangedListener = new IModelChangedListener() {
467         public void modelChanged(IModelDelta delta, IModelProxy proxy) {
468             if (delta.getElement() == getMemoryBlock())
469             {
470                 showTable();
471                 updateRenderingLabel(isVisible());
472             }
473         }};
474     
475     private IVirtualContentListener fViewerListener = new IVirtualContentListener() {
476         
477         private int startThreshold;
478         private int endThreshold;
479
480         public void handledAtBufferStart() {
481             if (getMemoryBlock() instanceof IMemoryBlockExtension)
482             {
483                 if (isDynamicLoad() && startThreshold != 0)
484                 {
485                     BigInteger JavaDoc address = getTopVisibleAddress();
486                     if (address != null && !isAtTopLimit())
487                         reloadTable(address);
488                 }
489             }
490         }
491
492         public void handleAtBufferEnd() {
493             if (getMemoryBlock() instanceof IMemoryBlockExtension)
494             {
495                 if (isDynamicLoad() && endThreshold != 0)
496                 {
497                     BigInteger JavaDoc address = getTopVisibleAddress();
498                     if (address != null && !isAtBottomLimit())
499                         reloadTable(address);
500                 }
501             }
502         }
503
504         public int getThreshold(int bufferEndOrStart) {
505             
506             int threshold = DEFAULT_BUFFER_THRESHOLD;
507             
508             if (bufferEndOrStart == IVirtualContentListener.BUFFER_START)
509             {
510                 if (threshold > getPreBufferSize())
511                 {
512                     threshold = getPreBufferSize();
513                 }
514             }
515             else
516             {
517                 if (threshold > getPostBufferSize())
518                 {
519                     threshold = getPostBufferSize();
520                 }
521             }
522             
523             if (bufferEndOrStart == IVirtualContentListener.BUFFER_START)
524                 startThreshold = threshold;
525             else
526                 endThreshold = threshold;
527             
528             return threshold;
529         }};
530         
531     private IPresentationErrorListener fPresentationErrorListener = new IPresentationErrorListener() {
532         public void handlePresentationFailure(IStatusMonitor monitor, IStatus status) {
533             showMessage(status.getMessage());
534         }};
535     
536     
537     /**
538      * Constructs a new table rendering of the specified type.
539      *
540      * @param renderingId memory rendering type identifier
541      */

542     public AbstractAsyncTableRendering(String JavaDoc renderingId) {
543         super(renderingId);
544     }
545
546     
547     /* (non-Javadoc)
548      * @see org.eclipse.debug.ui.memory.IResettableMemoryRendering#resetRendering()
549      */

550     public void resetRendering() throws DebugException {
551         BigInteger JavaDoc baseAddress = fContentDescriptor.getContentBaseAddress();
552
553         fTableViewer.setSelection(baseAddress);
554         reloadTable(baseAddress);
555         fTableViewer.setTopIndex(baseAddress);
556         if (!isDynamicLoad())
557         {
558             updateSyncPageStartAddress(baseAddress);
559         }
560         
561         updateSyncSelectedAddress(baseAddress);
562         updateSyncTopAddress(baseAddress);
563     }
564
565     public Control createControl(Composite parent) {
566         
567         fPageBook = new PageBook(parent, SWT.NONE);
568         createMessagePage(fPageBook);
569         createTableViewer(fPageBook);
570         addListeners();
571         
572         return fPageBook;
573     }
574     
575     /**
576      * Create the error page of this rendering
577      * @param parent
578      */

579     private void createMessagePage(Composite parent)
580     {
581         if (fTextViewer == null)
582         {
583             fTextViewer = new TextViewer(parent, SWT.WRAP);
584             fTextViewer.setDocument(new Document());
585             StyledText styleText = fTextViewer.getTextWidget();
586             styleText.setEditable(false);
587             styleText.setEnabled(false);
588         }
589     }
590     
591     /**
592      * @param parent
593      */

594     private void createTableViewer(final Composite parent)
595     {
596         StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
597         IMemoryRenderingType type = DebugUITools.getMemoryRenderingManager().getRenderingType(getRenderingId());
598         buffer.append(type.getLabel());
599         buffer.append(": "); //$NON-NLS-1$
600
buffer.append(DebugUIMessages.AbstractAsyncTableRendering_2);
601         
602         Job job = new Job(buffer.toString()) {
603
604             protected IStatus run(IProgressMonitor monitor) {
605                 
606                 // gather information from memory block
607
initAddressableSize();
608                 final BigInteger JavaDoc topVisibleAddress = getInitialTopVisibleAddress();
609                 BigInteger JavaDoc mbBaseAddress = null;
610                 try {
611                     mbBaseAddress = getMemoryBlockBaseAddress();
612                 } catch (DebugException e) {
613                     fError = true;
614                     showMessage(e.getMessage());
615                 }
616                 
617                 // if it takes too long to get the base address, and user has canceled
618
// remove this rendering.
619
if (monitor.isCanceled())
620                 {
621                     getMemoryRenderingContainer().removeMemoryRendering(AbstractAsyncTableRendering.this);
622                     return Status.CANCEL_STATUS;
623                 }
624                 
625                 final BigInteger JavaDoc finalMbBaseAddress = mbBaseAddress;
626                 final BigInteger JavaDoc initialSelectedAddress = getInitialSelectedAddress();
627                 
628                 if (monitor.isCanceled())
629                 {
630                     getMemoryRenderingContainer().removeMemoryRendering(AbstractAsyncTableRendering.this);
631                     return Status.CANCEL_STATUS;
632                 }
633                 
634                 createContentDescriptor(topVisibleAddress);
635                 
636                 // if it takes too long to get other information, and user has canceled
637
// remove this rendering.
638
if (monitor.isCanceled())
639                 {
640                     getMemoryRenderingContainer().removeMemoryRendering(AbstractAsyncTableRendering.this);
641                     return Status.CANCEL_STATUS;
642                 }
643                 
644                 // batch update on UI thread
645
UIJob uiJob = new UIJob("Create Table Viewer UI Job"){ //$NON-NLS-1$
646
public IStatus runInUIThread(IProgressMonitor progressMonitor) {
647                         
648                         if (fPageBook.isDisposed())
649                             return Status.OK_STATUS;
650                         
651                         fSashForm = new SashForm(parent, SWT.VERTICAL);
652                         fTableViewer = new AsyncTableRenderingViewer(AbstractAsyncTableRendering.this, fSashForm, SWT.VIRTUAL | SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.HIDE_SELECTION | SWT.BORDER);
653
654                         GridData data = new GridData(GridData.FILL_BOTH);
655                         fTableViewer.getControl().setLayoutData(data);
656                         
657                         createGoToAddressComposite(fSashForm);
658                         hideGotoAddressComposite();
659                         
660                         IMemoryRenderingSite site = getMemoryRenderingContainer().getMemoryRenderingSite();
661                         IMemoryRenderingContainer container = getMemoryRenderingContainer();
662                         fPresentationContext = new MemoryViewPresentationContext(site, container, AbstractAsyncTableRendering.this);
663                         fTableViewer.setContext(fPresentationContext);
664                         
665                         // must call this after the context is created as the information is stored in the context
666
getDynamicLoadFromPreference();
667                         getPageSizeFromPreference();
668                         
669                         int numberOfLines = getNumLinesToLoad();
670                         fContentDescriptor.setNumLines(numberOfLines);
671                         
672                         if (numberOfLines == 0)
673                         {
674                             // if the table viewer is not initialized yet, add listener
675
// and load table when we can get the height of the table
676
fTableViewer.getTable().addPaintListener(new PaintListener() {
677                                 public void paintControl(PaintEvent e) {
678                                     fTableViewer.getTable().removePaintListener(this);
679                                     fContentDescriptor.setNumLines(getNumLinesToLoad());
680                                     refresh();
681                                 }});
682                         }
683                         
684                         BigInteger JavaDoc baseAddress = finalMbBaseAddress;
685                         if (baseAddress == null)
686                             baseAddress = BigInteger.ZERO;
687                         
688                         if (!(getMemoryBlock() instanceof IMemoryBlockExtension) || !isDynamicLoad())
689                         {
690                             // If not extended memory block, do not create any buffer
691
// no scrolling
692
fContentDescriptor.setPreBuffer(0);
693                             fContentDescriptor.setPostBuffer(0);
694                         }
695                         
696                         setupInitialFormat();
697                         fTableViewer.setCellModifier(newInternalCellModifier());
698                         fTableViewer.getTable().setHeaderVisible(true);
699                         fTableViewer.getTable().setLinesVisible(true);
700                         fTableViewer.addPresentationErrorListener(fPresentationErrorListener);
701                         fTableViewer.setInput(getMemoryBlock());
702                         fTableViewer.resizeColumnsToPreferredSize();
703                         fTableViewer.setTopIndex(topVisibleAddress);
704                         
705                         fTableViewer.setSelection(initialSelectedAddress);
706
707                         // SET UP FONT
708
// set to a non-proportional font
709
fTableViewer.getTable().setFont(JFaceResources.getFont(IInternalDebugUIConstants.FONT_NAME));
710                         
711                         if (!fError)
712                             showTable();
713                         
714                         fTableViewer.addVirtualContentListener(fViewerListener);
715                         
716                         // create context menu
717
// create pop up menu for the rendering
718
createActions();
719                         IMenuListener menuListener = new IMenuListener() {
720                             public void menuAboutToShow(IMenuManager mgr) {
721                                 fillContextMenu(mgr);
722                             }
723                         };
724                         createPopupMenu(fTableViewer.getControl(), menuListener);
725                         createPopupMenu(fTableViewer.getCursor(), menuListener);
726                         
727                         fTableViewer.addSelectionChangedListener(fViewerSelectionChangedListener);
728                         fTableViewer.getTable().getVerticalBar().addSelectionListener(fScrollBarSelectionListener);
729                         
730                         // add resize listener to figure out number of visible lines
731
// so that the viewer get refreshed with the correct number of lines on the
732
// next refresh request
733
fTableViewer.getTable().addListener(SWT.Resize, new Listener() {
734                             public void handleEvent(Event event) {
735                                 if (!fTableViewer.getTable().isDisposed())
736                                     fContentDescriptor.setNumLines(getNumLinesToLoad());
737                             }});
738                         
739                         createToolTip();
740                         
741                         if (isActivated())
742                         {
743                             activatePageActions();
744                         }
745                         
746                         // now the rendering is successfully created
747
fIsCreated = true;
748                         
749                         return Status.OK_STATUS;
750                     }};
751                 uiJob.setSystem(true);
752                 uiJob.schedule();
753                     
754                 return Status.OK_STATUS;
755
756             }};
757             
758         job.schedule();
759     }
760     
761     /**
762      * Create popup menu for this rendering
763      * @param control - control to create the popup menu for
764      * @param menuListener - listener to notify when popup menu is about to show
765      */

766     private void createPopupMenu(Control control, IMenuListener menuListener)
767     {
768         IMemoryRenderingContainer container = getMemoryRenderingContainer();
769         if (fMenuMgr == null)
770         {
771             fMenuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
772
fMenuMgr.setRemoveAllWhenShown(true);
773             IMemoryRenderingSite site = container.getMemoryRenderingSite();
774             String JavaDoc menuId = container.getId();
775                         
776             ISelectionProvider selProvider = site.getSite().getSelectionProvider();
777             
778             addMenuListener(menuListener);
779
780             site.getSite().registerContextMenu(menuId, fMenuMgr, selProvider);
781         }
782         
783         addMenuListener(menuListener);
784         
785         Menu popupMenu = fMenuMgr.createContextMenu(control);
786         control.setMenu(popupMenu);
787     }
788
789
790     private void addMenuListener(IMenuListener menuListener) {
791         if (fMenuListeners == null)
792             fMenuListeners = new ArrayList JavaDoc();
793         
794         if (!fMenuListeners.contains(menuListener))
795         {
796             fMenuMgr.addMenuListener(menuListener);
797             fMenuListeners.add(menuListener);
798         }
799     }
800
801     private BigInteger JavaDoc getInitialSelectedAddress() {
802         // figure out selected address
803
BigInteger JavaDoc selectedAddress = (BigInteger JavaDoc) getSynchronizedProperty(AbstractAsyncTableRendering.PROPERTY_SELECTED_ADDRESS);
804         if (selectedAddress == null)
805         {
806             if (getMemoryBlock() instanceof IMemoryBlockExtension) {
807                 try {
808                     selectedAddress = ((IMemoryBlockExtension) getMemoryBlock()).getBigBaseAddress();
809                 } catch (DebugException e) {
810                     selectedAddress = BigInteger.ZERO;
811                 }
812                 
813                 if (selectedAddress == null) {
814                     selectedAddress =BigInteger.ZERO;
815                 }
816
817             } else {
818                 long address = getMemoryBlock().getStartAddress();
819                 selectedAddress = BigInteger.valueOf(address);
820             }
821         }
822         return selectedAddress;
823     }
824     
825     private void addListeners()
826     {
827         DebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
828         addRenderingToSyncService();
829         JFaceResources.getFontRegistry().addListener(this);
830     }
831     
832     private void removeListeners()
833     {
834         DebugUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this);
835         removeRenderingFromSyncService();
836         JFaceResources.getFontRegistry().removeListener(this);
837         
838         Iterator JavaDoc iter = fMenuListeners.iterator();
839         while (iter.hasNext())
840         {
841             fMenuMgr.removeMenuListener((IMenuListener)iter.next());
842         }
843         
844         fMenuListeners.clear();
845     }
846     
847     private void addRenderingToSyncService()
848     {
849         IMemoryRenderingSynchronizationService syncService = getMemoryRenderingContainer().getMemoryRenderingSite().getSynchronizationService();
850         
851         if (syncService == null)
852             return;
853         
854         syncService.addPropertyChangeListener(this, null);
855     }
856     
857     private void removeRenderingFromSyncService()
858     {
859         IMemoryRenderingSynchronizationService syncService = getMemoryRenderingContainer().getMemoryRenderingSite().getSynchronizationService();
860         
861         if (syncService == null)
862             return;
863         
864         syncService.removePropertyChangeListener(this);
865     }
866     
867     private void initAddressableSize()
868     {
869         // set up addressable size and figure out number of bytes required per line
870
fAddressableSize = -1;
871         try {
872             if (getMemoryBlock() instanceof IMemoryBlockExtension)
873                 fAddressableSize = ((IMemoryBlockExtension)getMemoryBlock()).getAddressableSize();
874             else
875                 fAddressableSize = 1;
876         } catch (DebugException e1) {
877             DebugUIPlugin.log(e1);
878             // log error and default to 1
879
fAddressableSize = 1;
880             return;
881             
882         }
883         if (fAddressableSize < 1)
884         {
885             DebugUIPlugin.logErrorMessage("Invalid addressable size"); //$NON-NLS-1$
886
fAddressableSize = 1;
887         }
888     }
889     
890     private BigInteger JavaDoc getInitialTopVisibleAddress() {
891         BigInteger JavaDoc topVisibleAddress = (BigInteger JavaDoc) getSynchronizedProperty(AbstractAsyncTableRendering.PROPERTY_TOP_ADDRESS);
892         if (topVisibleAddress == null)
893         {
894             if (getMemoryBlock() instanceof IMemoryBlockExtension)
895             {
896                 try {
897                     topVisibleAddress = ((IMemoryBlockExtension)getMemoryBlock()).getBigBaseAddress();
898                 } catch (DebugException e1) {
899                     topVisibleAddress = new BigInteger JavaDoc("0"); //$NON-NLS-1$
900
}
901             }
902             else
903             {
904                 topVisibleAddress = BigInteger.valueOf(getMemoryBlock().getStartAddress());
905             }
906         }
907         return topVisibleAddress;
908     }
909     
910     private void setupInitialFormat() {
911         
912         boolean validated = validateInitialFormat();
913         
914         if (!validated)
915         {
916             // pop up dialog to ask user for default values
917
StringBuffer JavaDoc msgBuffer = new StringBuffer JavaDoc(DebugUIMessages.AbstractTableRendering_20);
918             msgBuffer.append(" "); //$NON-NLS-1$
919
msgBuffer.append(this.getLabel());
920             msgBuffer.append("\n\n"); //$NON-NLS-1$
921
msgBuffer.append(DebugUIMessages.AbstractTableRendering_16);
922             msgBuffer.append("\n"); //$NON-NLS-1$
923
msgBuffer.append(DebugUIMessages.AbstractTableRendering_18);
924             msgBuffer.append("\n\n"); //$NON-NLS-1$
925

926             int bytePerLine = fBytePerLine;
927             int columnSize = fColumnSize;
928             
929             // initialize this value to populate the dialog properly
930
fBytePerLine = getDefaultRowSize() / getAddressableSize();
931             fColumnSize = getDefaultColumnSize() / getAddressableSize();
932
933             FormatTableRenderingDialog dialog = new FormatTableRenderingDialog(this, DebugUIPlugin.getShell());
934             dialog.openError(msgBuffer.toString());
935             
936             // restore to original value before formatting
937
fBytePerLine = bytePerLine;
938             fColumnSize = columnSize;
939             
940             bytePerLine = dialog.getRowSize() * getAddressableSize();
941             columnSize = dialog.getColumnSize() * getAddressableSize();
942             
943             format(bytePerLine, columnSize);
944         }
945         else
946         {
947             // Row size is stored as number of addressable units in preference store
948
int bytePerLine = getDefaultRowSize();
949             // column size is now stored as number of addressable units
950
int columnSize = getDefaultColumnSize();
951             
952             // format memory block with specified "bytesPerLine" and "columnSize"
953
boolean ok = format(bytePerLine, columnSize);
954             
955             if (!ok)
956             {
957                 // this is to ensure that the rest of the rendering can be created
958
// and we can recover from a format error
959
format(bytePerLine, bytePerLine);
960             }
961         }
962     }
963     
964     private boolean validateInitialFormat()
965     {
966         int rowSize = getDefaultRowSize();
967         int columnSize = getDefaultColumnSize();
968         
969         if (rowSize < columnSize || rowSize % columnSize != 0 || rowSize == 0 || columnSize == 0)
970         {
971             return false;
972         }
973         return true;
974     }
975
976     /* (non-Javadoc)
977      * @see org.eclipse.debug.ui.memory.IMemoryRendering#getControl()
978      */

979     public Control getControl() {
980         return fPageBook.getParent();
981     }
982
983     /* (non-Javadoc)
984      * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
985      */

986     public void propertyChange(PropertyChangeEvent event) {
987         if (!fIsCreated)
988             return;
989         
990         // if memory view table font has changed
991
if (event.getProperty().equals(IInternalDebugUIConstants.FONT_NAME))
992         {
993             if (!fIsDisposed)
994             {
995                 Font memoryViewFont = JFaceResources.getFont(IInternalDebugUIConstants.FONT_NAME);
996                 setFont(memoryViewFont);
997             }
998             return;
999         }
1000        
1001        Object JavaDoc evtSrc = event.getSource();
1002
1003        // always update page size, only refresh if the table is visible
1004
if (event.getProperty().equals(IDebugPreferenceConstants.PREF_TABLE_RENDERING_PAGE_SIZE)) {
1005            getPageSizeFromPreference();
1006        }
1007        if (event.getProperty().equals(IDebugPreferenceConstants.PREF_TABLE_RENDERING_PRE_BUFFER_SIZE))
1008        {
1009            getPreBufferSizeFromPreference();
1010            fContentDescriptor.setPreBuffer(getPreBufferSize());
1011        }
1012        if (event.getProperty().equals(IDebugPreferenceConstants.PREF_TABLE_RENDERING_POST_BUFFER_SIZE))
1013        {
1014            getPostBufferSizeFromPreference();
1015            fContentDescriptor.setPostBuffer(getPostBufferSize());
1016        }
1017        
1018        // do not handle event if the rendering is displaying an error
1019
// or if it's not visible
1020
if (isDisplayingError() || !isVisible())
1021        {
1022            handlePropertiesChangeWhenHidden(event);
1023            return;
1024        }
1025        
1026        
1027        if (event.getProperty().equals(IDebugUIConstants.PREF_PADDED_STR) ||
1028            event.getProperty().equals(IDebugUIConstants.PREF_CHANGED_DEBUG_ELEMENT_COLOR) ||
1029            event.getProperty().equals(IDebugUIConstants.PREF_MEMORY_HISTORY_KNOWN_COLOR) ||
1030            event.getProperty().equals(IDebugUIConstants.PREF_MEMORY_HISTORY_UNKNOWN_COLOR))
1031        {
1032            if (!fIsDisposed)
1033            {
1034                fTableViewer.refresh(false);
1035            }
1036            return;
1037        }
1038        
1039        if (event.getProperty().equals(IDebugPreferenceConstants.PREF_TABLE_RENDERING_PRE_BUFFER_SIZE) ||
1040            event.getProperty().equals(IDebugPreferenceConstants.PREF_TABLE_RENDERING_POST_BUFFER_SIZE))
1041        {
1042            if (!fIsDisposed)
1043            {
1044                fTableViewer.refresh(true);
1045            }
1046            return;
1047        }
1048        
1049        if (event.getProperty().equals(IDebugPreferenceConstants.PREF_DYNAMIC_LOAD_MEM)) {
1050            handleDyanicLoadChanged();
1051            return;
1052        }
1053        
1054        if (event.getProperty().equals(IDebugPreferenceConstants.PREF_TABLE_RENDERING_PAGE_SIZE)) {
1055            if (!isDynamicLoad())
1056            {
1057                int pageSize = DebugUIPlugin.getDefault().getPreferenceStore().getInt(IDebugPreferenceConstants.PREF_TABLE_RENDERING_PAGE_SIZE);
1058                handlePageSizeChanged(pageSize);
1059            }
1060            return;
1061        }
1062        
1063        if (evtSrc == this)
1064            return;
1065        
1066        if (evtSrc instanceof IMemoryRendering)
1067        {
1068            IMemoryRendering rendering = (IMemoryRendering)evtSrc;
1069            IMemoryBlock memoryBlock = rendering.getMemoryBlock();
1070            
1071            // do not handle event from renderings displaying other memory blocks
1072
if (memoryBlock != getMemoryBlock())
1073                return;
1074        }
1075    
1076        String JavaDoc propertyName = event.getProperty();
1077        Object JavaDoc value = event.getNewValue();
1078        
1079        if (propertyName.equals(AbstractAsyncTableRendering.PROPERTY_SELECTED_ADDRESS) && value instanceof BigInteger JavaDoc)
1080        {
1081            selectedAddressChanged((BigInteger JavaDoc)value);
1082        }
1083        else if (propertyName.equals(AbstractAsyncTableRendering.PROPERTY_COL_SIZE) && value instanceof Integer JavaDoc)
1084        {
1085            columnSizeChanged(((Integer JavaDoc)value).intValue());
1086        }
1087        else if (propertyName.equals(AbstractAsyncTableRendering.PROPERTY_ROW_SIZE) && value instanceof Integer JavaDoc)
1088        {
1089            rowSizeChanged(((Integer JavaDoc)value).intValue());
1090        }
1091        else if (propertyName.equals(AbstractAsyncTableRendering.PROPERTY_TOP_ADDRESS) && value instanceof BigInteger JavaDoc)
1092        {
1093            topVisibleAddressChanged((BigInteger JavaDoc)value);
1094        }
1095        else if (propertyName.equals(IInternalDebugUIConstants.PROPERTY_PAGE_START_ADDRESS) && value instanceof BigInteger JavaDoc)
1096        {
1097            handlePageStartAddressChanged((BigInteger JavaDoc)value);
1098        }
1099    }
1100
1101    /**
1102     *
1103     */

1104    private void handlePageSizeChanged(int pageSize) {
1105        fPageSize = pageSize;
1106        // only refresh if in non-auto-load mode
1107
fContentDescriptor.setNumLines(pageSize);
1108        refresh();
1109    }
1110    
1111    private void handlePropertiesChangeWhenHidden(PropertyChangeEvent event)
1112    {
1113        if (fPendingSyncProperties == null)
1114            return;
1115        
1116        String JavaDoc propertyName = event.getProperty();
1117        Object JavaDoc value = event.getNewValue();
1118        
1119        if (event.getSource() instanceof IMemoryRendering)
1120        {
1121            IMemoryRendering rendering = (IMemoryRendering)event.getSource();
1122            if (rendering == this || rendering.getMemoryBlock() != getMemoryBlock())
1123            {
1124                return;
1125            }
1126        }
1127        
1128        if (propertyName.equals(AbstractAsyncTableRendering.PROPERTY_COL_SIZE) && value instanceof Integer JavaDoc)
1129        {
1130            fPendingSyncProperties.setColumnSize(((Integer JavaDoc)value).intValue());
1131        }
1132        else if (propertyName.equals(AbstractAsyncTableRendering.PROPERTY_ROW_SIZE) && value instanceof Integer JavaDoc)
1133        {
1134            fPendingSyncProperties.setRowSize(((Integer JavaDoc)value).intValue());
1135        }
1136        
1137        else if (propertyName.equals(AbstractAsyncTableRendering.PROPERTY_SELECTED_ADDRESS) && value instanceof BigInteger JavaDoc)
1138        {
1139            fPendingSyncProperties.setSelectedAddress((BigInteger JavaDoc)value);
1140        }
1141        else if (propertyName.equals(AbstractAsyncTableRendering.PROPERTY_TOP_ADDRESS) && value instanceof BigInteger JavaDoc)
1142        {
1143            fPendingSyncProperties.setTopVisibleAddress((BigInteger JavaDoc)value);
1144        }
1145        else if (propertyName.equals(IInternalDebugUIConstants.PROPERTY_PAGE_START_ADDRESS) && value instanceof BigInteger JavaDoc)
1146        {
1147            fPendingSyncProperties.setPageStartAddress((BigInteger JavaDoc)value);
1148        }
1149        else if (event.getProperty().equals(IDebugPreferenceConstants.PREF_TABLE_RENDERING_PAGE_SIZE)) {
1150            int pageSize = DebugUIPlugin.getDefault().getPreferenceStore().getInt(IDebugPreferenceConstants.PREF_TABLE_RENDERING_PAGE_SIZE);
1151            fPendingSyncProperties.setPageSize(pageSize);
1152        }
1153    }
1154    
1155    private void topVisibleAddressChanged(final BigInteger JavaDoc address)
1156    {
1157        final Runnable JavaDoc runnable = new Runnable JavaDoc() {
1158            public void run() {
1159                if (fTableViewer.getTable().isDisposed())
1160                    return;
1161                
1162                doTopVisibleAddressChanged(address);
1163            }};
1164        runOnUIThread(runnable);
1165    }
1166    
1167    /**
1168     * @param address
1169     */

1170    private void doTopVisibleAddressChanged(final BigInteger JavaDoc address) {
1171        if (fIsDisposed)
1172            return;
1173        
1174        if (!isDynamicLoad())
1175        {
1176            fTableViewer.setTopIndex(address);
1177            fTableViewer.topIndexChanged();
1178            return;
1179        }
1180        
1181        if (!isAtTopBuffer(address) && !isAtBottomBuffer(address))
1182        {
1183            fTableViewer.setTopIndex(address);
1184            fTableViewer.topIndexChanged();
1185        }
1186        else
1187        {
1188            reloadTable(address);
1189        }
1190    }
1191    
1192    private boolean isAtBottomBuffer(BigInteger JavaDoc address)
1193    {
1194        int idx = fTableViewer.indexOf(address);
1195        if (idx < 0)
1196            return true;
1197        
1198        int bottomIdx = idx + getNumberOfVisibleLines();
1199        int elementsCnt = fTableViewer.getVirtualContentModel().getElements().length;
1200        int numLinesLeft = elementsCnt - bottomIdx;
1201        
1202        if (numLinesLeft < fViewerListener.getThreshold(IVirtualContentListener.BUFFER_END))
1203            return true;
1204        
1205        return false;
1206    }
1207    
1208    private boolean isAtTopBuffer(BigInteger JavaDoc address)
1209    {
1210        int topIdx = fTableViewer.indexOf(address);
1211        if (topIdx < fViewerListener.getThreshold(IVirtualContentListener.BUFFER_START))
1212            return true;
1213        
1214        return false;
1215    }
1216    
1217    private void runOnUIThread(final Runnable JavaDoc runnable)
1218    {
1219        if (Display.getCurrent() != null)
1220        {
1221            runnable.run();
1222        }
1223        else
1224        {
1225            UIJob job = new UIJob("Async Table Rendering UI Job"){ //$NON-NLS-1$
1226

1227                public IStatus runInUIThread(IProgressMonitor monitor) {
1228                    runnable.run();
1229                    return Status.OK_STATUS;
1230                }};
1231            job.setSystem(true);
1232            job.schedule();
1233        }
1234    }
1235    
1236    private void selectedAddressChanged(final BigInteger JavaDoc address)
1237    {
1238        Runnable JavaDoc runnable = new Runnable JavaDoc() {
1239
1240            public void run() {
1241                
1242                if (fTableViewer.getTable().isDisposed())
1243                    return;
1244                        
1245                // call this to make the table viewer to reload when needed
1246
int i = fTableViewer.indexOf(address);
1247                if (i < 0)
1248                {
1249                    // the model may not have been populated yet,
1250
// try to predict if the address will be in the buffer
1251
boolean contained = isAddressBufferred(address);
1252                    if (!contained)
1253                        topVisibleAddressChanged(address);
1254                }
1255                fTableViewer.setSelection(address);
1256            }
1257        };
1258        
1259        runOnUIThread(runnable);
1260    }
1261    
1262    private boolean isAddressBufferred(BigInteger JavaDoc address)
1263    {
1264        // figure out the buffer top address
1265
BigInteger JavaDoc loadAddress = fContentDescriptor.getLoadAddress();
1266        loadAddress = MemoryViewUtil.alignToBoundary(loadAddress, getAddressableUnitPerLine());
1267        int unitPerLine = getAddressableUnitPerLine();
1268        
1269        loadAddress = loadAddress.subtract(BigInteger.valueOf(getPreBufferSize() * unitPerLine));
1270        
1271        // figure out the buffer end address
1272
int numLines = fContentDescriptor.getNumLines();
1273        BigInteger JavaDoc bufferEnd = loadAddress.add(BigInteger.valueOf(fContentDescriptor.getPostBuffer()*unitPerLine));
1274        bufferEnd = bufferEnd.add(BigInteger.valueOf(numLines*unitPerLine + unitPerLine));
1275        
1276        // see if the address is contained based on current content descriptor
1277
if (address.compareTo(loadAddress) >= 0 && address.compareTo(bufferEnd) <= 0)
1278            return true;
1279        
1280        return false;
1281    }
1282    
1283    private void setFont(Font font)
1284    {
1285        // set font
1286
fTableViewer.getTable().setFont(font);
1287        fTableViewer.getCursor().setFont(font);
1288    }
1289    
1290    private int getDefaultColumnSize() {
1291        
1292        // default to global preference store
1293
IPreferenceStore prefStore = DebugUITools.getPreferenceStore();
1294        int columnSize = prefStore.getInt(IDebugPreferenceConstants.PREF_COLUMN_SIZE);
1295        // actual column size is number of addressable units * size of the addressable unit
1296
columnSize = columnSize * getAddressableSize();
1297        
1298        // check synchronized col size
1299
Integer JavaDoc colSize = (Integer JavaDoc)getSynchronizedProperty(AbstractAsyncTableRendering.PROPERTY_COL_SIZE);
1300        if (colSize != null)
1301        {
1302            // column size is stored as actual number of bytes in synchronizer
1303
int syncColSize = colSize.intValue();
1304            if (syncColSize > 0)
1305            {
1306                columnSize = syncColSize;
1307            }
1308        }
1309        else
1310        {
1311            IPersistableDebugElement elmt = (IPersistableDebugElement)getMemoryBlock().getAdapter(IPersistableDebugElement.class);
1312            int defaultColSize = -1;
1313            
1314            if (elmt != null)
1315            {
1316                if (elmt.supportsProperty(this, IDebugPreferenceConstants.PREF_COL_SIZE_BY_MODEL))
1317                    defaultColSize = getDefaultFromPersistableElement(IDebugPreferenceConstants.PREF_COL_SIZE_BY_MODEL);
1318            }
1319            
1320            if (defaultColSize <= 0)
1321            {
1322                // if not provided, get default by model
1323
defaultColSize = getDefaultColumnSizeByModel(getMemoryBlock().getModelIdentifier());
1324            }
1325            
1326            if (defaultColSize > 0)
1327                columnSize = defaultColSize * getAddressableSize();
1328        }
1329        return columnSize;
1330    }
1331
1332    private int getDefaultRowSize() {
1333        
1334        int rowSize = DebugUITools.getPreferenceStore().getInt(IDebugPreferenceConstants.PREF_ROW_SIZE);
1335        int bytePerLine = rowSize * getAddressableSize();
1336        
1337        // check synchronized row size
1338
Integer JavaDoc size = (Integer JavaDoc)getSynchronizedProperty(AbstractAsyncTableRendering.PROPERTY_ROW_SIZE);
1339        if (size != null)
1340        {
1341            // row size is stored as actual number of bytes in synchronizer
1342
int syncRowSize = size.intValue();
1343            if (syncRowSize > 0)
1344            {
1345                bytePerLine = syncRowSize;
1346            }
1347        }
1348        else
1349        {
1350            int defaultRowSize = -1;
1351            IPersistableDebugElement elmt = (IPersistableDebugElement)getMemoryBlock().getAdapter(IPersistableDebugElement.class);
1352            if (elmt != null)
1353            {
1354                if (elmt.supportsProperty(this, IDebugPreferenceConstants.PREF_ROW_SIZE_BY_MODEL))
1355                {
1356                    defaultRowSize = getDefaultFromPersistableElement(IDebugPreferenceConstants.PREF_ROW_SIZE_BY_MODEL);
1357                    return defaultRowSize * getAddressableSize();
1358                }
1359            }
1360            
1361            if (defaultRowSize <= 0)
1362                // no synchronized property, ask preference store by id
1363
defaultRowSize = getDefaultRowSizeByModel(getMemoryBlock().getModelIdentifier());
1364            
1365            if (defaultRowSize > 0)
1366                bytePerLine = defaultRowSize * getAddressableSize();
1367        }
1368        return bytePerLine;
1369    }
1370    
1371    /**
1372     * Returns the addressable size of this rendering's memory block in bytes.
1373     *
1374     * @return the addressable size of this rendering's memory block in bytes
1375     */

1376    public int getAddressableSize() {
1377        return fAddressableSize;
1378    }
1379    
1380    private Object JavaDoc getSynchronizedProperty(String JavaDoc propertyId)
1381    {
1382        IMemoryRenderingSynchronizationService syncService = getMemoryRenderingContainer().getMemoryRenderingSite().getSynchronizationService();
1383        
1384        if (syncService == null)
1385            return null;
1386        
1387        return syncService.getProperty(getMemoryBlock(), propertyId);
1388    }
1389    
1390    private int getDefaultFromPersistableElement(String JavaDoc propertyId) {
1391        int defaultValue = -1;
1392        IPersistableDebugElement elmt = (IPersistableDebugElement)getMemoryBlock().getAdapter(IPersistableDebugElement.class);
1393        if (elmt != null)
1394        {
1395            try {
1396                Object JavaDoc valueMB = elmt.getProperty(this, propertyId);
1397                if (valueMB != null && !(valueMB instanceof Integer JavaDoc))
1398                {
1399                    IStatus status = DebugUIPlugin.newErrorStatus("Model returned invalid type on " + propertyId, null); //$NON-NLS-1$
1400
DebugUIPlugin.log(status);
1401                }
1402                
1403                if (valueMB != null)
1404                {
1405                    Integer JavaDoc value = (Integer JavaDoc)valueMB;
1406                    defaultValue = value.intValue();
1407                }
1408            } catch (CoreException e) {
1409                DebugUIPlugin.log(e);
1410            }
1411        }
1412        return defaultValue;
1413    }
1414    
1415    /**
1416     * @param modelId
1417     * @return default number of addressable units per line for the model
1418     */

1419    private int getDefaultRowSizeByModel(String JavaDoc modelId)
1420    {
1421        int row = DebugUITools.getPreferenceStore().getInt(getRowPrefId(modelId));
1422        if (row == 0)
1423        {
1424            DebugUITools.getPreferenceStore().setValue(getRowPrefId(modelId), IDebugPreferenceConstants.PREF_ROW_SIZE_DEFAULT);
1425        }
1426        
1427        row = DebugUITools.getPreferenceStore().getInt(getRowPrefId(modelId));
1428        return row;
1429        
1430    }
1431    
1432    /**
1433     * @param modelId
1434     * @return default number of addressable units per column for the model
1435     */

1436    private int getDefaultColumnSizeByModel(String JavaDoc modelId)
1437    {
1438        int col = DebugUITools.getPreferenceStore().getInt(getColumnPrefId(modelId));
1439        if (col == 0)
1440        {
1441            DebugUITools.getPreferenceStore().setValue(getColumnPrefId(modelId), IDebugPreferenceConstants.PREF_COLUMN_SIZE_DEFAULT);
1442        }
1443        
1444        col = DebugUITools.getPreferenceStore().getInt(getColumnPrefId(modelId));
1445        return col;
1446    }
1447    
1448    
1449    private String JavaDoc getRowPrefId(String JavaDoc modelId) {
1450        String JavaDoc rowPrefId = IDebugPreferenceConstants.PREF_ROW_SIZE + ":" + modelId; //$NON-NLS-1$
1451
return rowPrefId;
1452    }
1453
1454    private String JavaDoc getColumnPrefId(String JavaDoc modelId) {
1455        String JavaDoc colPrefId = IDebugPreferenceConstants.PREF_COLUMN_SIZE + ":" + modelId; //$NON-NLS-1$
1456
return colPrefId;
1457    }
1458    
1459    /**
1460     * Format view tab based on the bytes per line and column.
1461     *
1462     * @param bytesPerLine - number of bytes per line, possible values: (1 / 2 / 4 / 8 / 16) * addressableSize
1463     * @param columnSize - number of bytes per column, possible values: (1 / 2 / 4 / 8 / 16) * addressableSize
1464     * @return true if format is successful, false, otherwise
1465     */

1466    public boolean format(int bytesPerLine, int columnSize)
1467    {
1468        
1469        // bytes per cell must be divisible to bytesPerLine
1470
if (bytesPerLine % columnSize != 0)
1471        {
1472            return false;
1473        }
1474        
1475        if (bytesPerLine < columnSize)
1476        {
1477            return false;
1478        }
1479        
1480        // do not format if the view tab is already in that format
1481
if(fBytePerLine == bytesPerLine && fColumnSize == columnSize){
1482            return false;
1483        }
1484        
1485        fBytePerLine = bytesPerLine;
1486        fColumnSize = columnSize;
1487        formatViewer();
1488
1489        updateSyncRowSize();
1490        updateSyncColSize();
1491        
1492        return true;
1493    }
1494        
1495    
1496    /**
1497     * Returns the number of addressable units per row.
1498     *
1499     * @return number of addressable units per row
1500     */

1501    public int getAddressableUnitPerLine() {
1502        return fBytePerLine / getAddressableSize();
1503    }
1504    
1505    /**
1506     * Returns the number of addressable units per column.
1507     *
1508     * @return number of addressable units per column
1509     */

1510    public int getAddressableUnitPerColumn() {
1511        return fColumnSize / getAddressableSize();
1512    }
1513    
1514    
1515    /**
1516     * This method estimates the number of visible lines in the rendering
1517     * table.
1518     * @return estimated number of visible lines in the table
1519     */

1520    private int getNumberOfVisibleLines()
1521    {
1522        if(fTableViewer == null)
1523            return -1;
1524        
1525        Table table = fTableViewer.getTable();
1526        int height = fTableViewer.getTable().getSize().y;
1527        
1528        // when table is not yet created, height is zero
1529
if (height == 0)
1530        {
1531            // make use of the table viewer to estimate table size
1532
height = fTableViewer.getTable().getParent().getSize().y;
1533        }
1534        
1535        if (height == 0)
1536        {
1537            return 0;
1538        }
1539        
1540        // height of border
1541
int border = fTableViewer.getTable().getHeaderHeight();
1542        
1543        // height of scroll bar
1544
int scroll = fTableViewer.getTable().getHorizontalBar().getSize().y;
1545
1546        // height of table is table's area minus border and scroll bar height
1547
height = height-border-scroll;
1548
1549        // calculate number of visible lines
1550
int lineHeight = getMinTableItemHeight(table);
1551        
1552        int numberOfLines = height/lineHeight;
1553        
1554        if (numberOfLines <= 0)
1555            return 0;
1556    
1557        return numberOfLines;
1558    }
1559    
1560    private int getMinTableItemHeight(Table table){
1561        
1562        // Hack to get around Linux GTK problem.
1563
// On Linux GTK, table items have variable item height as
1564
// carriage returns are actually shown in a cell. Some rows will be
1565
// taller than others. When calculating number of visible lines, we
1566
// need to find the smallest table item height. Otherwise, the rendering
1567
// underestimates the number of visible lines. As a result the rendering
1568
// will not be able to get more memory as needed.
1569
if (MemoryViewUtil.isLinuxGTK())
1570        {
1571            // check each of the items and find the minimum
1572
TableItem[] items = table.getItems();
1573            int minHeight = table.getItemHeight();
1574            for (int i=0; i<items.length; i++)
1575            {
1576                if (items[i].getData() != null)
1577                    minHeight = Math.min(items[i].getBounds(0).height, minHeight);
1578            }
1579            
1580            return minHeight;
1581                
1582        }
1583        return table.getItemHeight();
1584    }
1585    
1586    private BigInteger JavaDoc getMemoryBlockBaseAddress() throws DebugException
1587    {
1588        if (getMemoryBlock() instanceof IMemoryBlockExtension)
1589            return ((IMemoryBlockExtension)getMemoryBlock()).getBigBaseAddress();
1590        else
1591            return BigInteger.valueOf(getMemoryBlock().getStartAddress());
1592    }
1593    
1594    /**
1595     * Displays the given message on the error page
1596     * @param message - the message to display
1597     */

1598    protected void showMessage(final String JavaDoc message)
1599    {
1600        fSwitchPageJob.setShowMessagePage(true);
1601        fSwitchPageJob.setMessage(message);
1602        fSwitchPageJob.schedule();
1603    }
1604    
1605    /**
1606     * Returns the number of bytes displayed in a single column cell.
1607     *
1608     * @return the number of bytes displayed in a single column cell
1609     */

1610    public int getBytesPerColumn()
1611    {
1612        return fColumnSize;
1613    }
1614
1615    /**
1616     * Returns the number of bytes displayed in a row.
1617     *
1618     * @return the number of bytes displayed in a row
1619     */

1620    public int getBytesPerLine()
1621    {
1622        return fBytePerLine;
1623    }
1624    
1625    /**
1626     * Returns whether the error page is displayed.
1627     *
1628     * @return whether the error page is displayed
1629     */

1630    public boolean isDisplayingError()
1631    {
1632        return fShowMessage;
1633    }
1634    
1635    /**
1636     * Displays the content of the table viewer.
1637     */

1638    public void showTable()
1639    {
1640        fSwitchPageJob.setShowMessagePage(false);
1641        fSwitchPageJob.schedule();
1642    }
1643    
1644    private BigInteger JavaDoc getTopVisibleAddress() {
1645        
1646        if (fTableViewer == null)
1647            return BigInteger.valueOf(0);
1648
1649        Table table = fTableViewer.getTable();
1650        int topIndex = table.getTopIndex();
1651
1652        if (topIndex < 0) { return null; }
1653
1654        if (table.getItemCount() > topIndex)
1655        {
1656            MemorySegment topItem = (MemorySegment)table.getItem(topIndex).getData();
1657            if (topItem != null)
1658            {
1659                return topItem.getAddress();
1660            }
1661        }
1662        return null;
1663    }
1664    
1665    private synchronized void reloadTable(final BigInteger JavaDoc topAddress) {
1666        
1667        if (AsyncVirtualContentTableViewer.DEBUG_DYNAMIC_LOADING)
1668            System.out.println(this + " reload at: " + topAddress.toString(16)); //$NON-NLS-1$
1669

1670        fContentDescriptor.setLoadAddress(topAddress);
1671        fContentDescriptor.setNumLines(getNumLinesToLoad());
1672        fTableViewer.setTopIndex(topAddress);
1673        fTableViewer.refresh();
1674
1675    }
1676    
1677    private boolean isAtTopLimit()
1678    {
1679        BigInteger JavaDoc startAddress = fContentDescriptor.getStartAddress();
1680        startAddress = MemoryViewUtil.alignToBoundary(startAddress, getAddressableUnitPerLine());
1681        AbstractVirtualContentTableModel model = fTableViewer.getVirtualContentModel();
1682        
1683        if (model != null)
1684        {
1685            Object JavaDoc key = model.getKey(0);
1686            if (key instanceof BigInteger JavaDoc)
1687            {
1688                BigInteger JavaDoc startBufferAddress = (BigInteger JavaDoc)key;
1689                startBufferAddress = MemoryViewUtil.alignToBoundary(startBufferAddress, getAddressableUnitPerLine());
1690                
1691                if (startAddress.compareTo(startBufferAddress) == 0)
1692                    return true;
1693            }
1694        }
1695        return false;
1696    }
1697    
1698    private boolean isAtBottomLimit()
1699    {
1700        BigInteger JavaDoc endAddress = fContentDescriptor.getEndAddress();
1701        endAddress = MemoryViewUtil.alignToBoundary(endAddress, getAddressableUnitPerLine());
1702        
1703        AbstractVirtualContentTableModel model = fTableViewer.getVirtualContentModel();
1704        if (model != null)
1705        {
1706            int numElements = model.getElements().length;
1707            Object JavaDoc key = model.getKey(numElements-1);
1708            if (key instanceof BigInteger JavaDoc)
1709            {
1710                BigInteger JavaDoc endBufferAddress = (BigInteger JavaDoc)key;
1711                endBufferAddress = MemoryViewUtil.alignToBoundary(endBufferAddress, getAddressableUnitPerLine());
1712                
1713                if (endAddress.compareTo(endBufferAddress) == 0)
1714                    return true;
1715            }
1716        }
1717        
1718        return false;
1719    }
1720    
1721    private void formatViewer() {
1722        
1723        fTableViewer.disposeColumns();
1724        fTableViewer.disposeCellEditors();
1725        doFormatTable();
1726        fTableViewer.setColumnHeaders(getColumnProperties());
1727        fTableViewer.showColumnHeader(true);
1728        
1729        Table table = fTableViewer.getTable();
1730        int colCnt = table.getColumnCount();
1731        CellEditor[] editors = new CellEditor[fTableViewer.getTable().getColumnCount()];
1732        for (int i=0; i<colCnt; i++)
1733        {
1734            editors[i] = createCellEditor(table, i);
1735        }
1736        
1737        fTableViewer.setCellEditors(editors);
1738        
1739        fTableViewer.formatViewer();
1740        
1741        // This resize needs to happen after the viewer has finished
1742
// getting the labels.
1743
// This fix is a hack to delay the resize until the viewer has a chance to get
1744
// the setData event from the UI thread. Otherwise, the columns will be
1745
// squeezed together.
1746
UIJob job = new UIJob("resize to fit"){ //$NON-NLS-1$
1747
public IStatus runInUIThread(IProgressMonitor monitor) {
1748                resizeColumnsToPreferredSize();
1749                return Status.OK_STATUS;
1750            }};
1751        
1752        job.setSystem(true);
1753        job.schedule();
1754    }
1755
1756    private void doFormatTable() {
1757        int bytesPerLine = getBytesPerLine();
1758        int columnSize = getBytesPerColumn();
1759        int numColumns = bytesPerLine/columnSize;
1760        
1761        Table table = fTableViewer.getTable();
1762        TableColumn column0 = new TableColumn(table,SWT.LEFT,0);
1763        column0.setText(DebugUIMessages.AbstractTableRendering_2);
1764        
1765        // create new byte columns
1766
TableColumn [] byteColumns = new TableColumn[numColumns];
1767        for (int i=0;i<byteColumns.length; i++)
1768        {
1769            TableColumn column = new TableColumn(table, SWT.LEFT, i+1);
1770            byteColumns[i] = column;
1771        }
1772        
1773        //Empty column for cursor navigation
1774
TableColumn emptyCol = new TableColumn(table,SWT.LEFT,byteColumns.length+1);
1775        emptyCol.setText(" "); //$NON-NLS-1$
1776
emptyCol.setWidth(1);
1777        emptyCol.setResizable(false);
1778        table.setHeaderVisible(true);
1779        
1780        // allow clients to override column labels
1781
setColumnHeadings();
1782        
1783    }
1784    
1785    private String JavaDoc[] getColumnProperties()
1786    {
1787        int numColumns = getAddressableUnitPerLine()/getAddressableUnitPerColumn();
1788        // +2 to include properties for address and navigation column
1789
String JavaDoc[] columnProperties = new String JavaDoc[numColumns+2];
1790        columnProperties[0] = TableRenderingLine.P_ADDRESS;
1791        
1792        int addressableUnit = getAddressableUnitPerColumn();
1793
1794        // use column beginning offset to the row address as properties
1795
for (int i=1; i<columnProperties.length-1; i++)
1796        {
1797            // column properties are stored as number of addressable units from the
1798
// the line address
1799
columnProperties[i] = Integer.toHexString((i-1)*addressableUnit);
1800        }
1801        
1802        // Empty column for cursor navigation
1803
columnProperties[columnProperties.length-1] = " "; //$NON-NLS-1$
1804
return columnProperties;
1805    }
1806    
1807   /**
1808     * Create a cell editor from the specified composite and column.
1809     * @param composite parent composite that the cell editor is to be created from.
1810     * @param column the column where the cell editor is required
1811     * @return the cell editor for editing memory
1812     *
1813     * @since 3.3
1814     *
1815     */

1816    protected CellEditor createCellEditor(Composite composite, int column) {
1817       
1818       return new TextCellEditor(composite);
1819   }
1820       
1821   
1822   private ICellModifier newInternalCellModifier()
1823   {
1824       return new AsyncTableRenderingCellModifier(this, createCellModifier());
1825   }
1826   
1827    /**
1828     * Create a custom cell modifier for this rendering. Return null
1829     * if the default cell modifier is to be used.
1830     * @return the cell modifier for this rendering, or <code>null</code> if the
1831     * default cell modifier is to be used.
1832     *
1833     * @since 3.3
1834     *
1835     */

1836    protected ICellModifier createCellModifier() {
1837       return null;
1838    }
1839    
1840    /* (non-Javadoc)
1841     * @see org.eclipse.debug.ui.memory.AbstractMemoryRendering#dispose()
1842     */

1843    public void dispose() {
1844        
1845        if (fIsDisposed)
1846            return;
1847        
1848        fIsDisposed = true;
1849        
1850        removeListeners();
1851        
1852        if (fMenuMgr != null)
1853        {
1854            fMenuMgr.removeAll();
1855            fMenuMgr.dispose();
1856            fMenuMgr = null;
1857        }
1858        
1859        if (fTableViewer != null)
1860        {
1861            if (fViewerListener != null)
1862                fTableViewer.removeVirtualContentListener(fViewerListener);
1863            
1864            if (fPresentationErrorListener != null)
1865                fTableViewer.removePresentationErrorListener(fPresentationErrorListener);
1866            
1867            fTableViewer.removeSelectionChangedListener(fViewerSelectionChangedListener);
1868            fTableViewer.getTable().getVerticalBar().removeSelectionListener(fScrollBarSelectionListener);
1869            
1870            fTableViewer.dispose();
1871        }
1872        
1873        fIsDisposed = true;
1874        
1875        super.dispose();
1876    }
1877    
1878    /**
1879     * Updates the label of this rendering, optionally displaying the
1880     * base address of this rendering's memory block.
1881     *
1882     * @param showAddress whether to display the base address of this
1883     * rendering's memory block in this rendering's label
1884     */

1885    protected void updateRenderingLabel(final boolean showAddress)
1886    {
1887        Job job = new Job("Update Rendering Label"){ //$NON-NLS-1$
1888
protected IStatus run(IProgressMonitor monitor) {
1889                if (fIsDisposed)
1890                    return Status.OK_STATUS;
1891                fLabel = buildLabel(showAddress);
1892                firePropertyChangedEvent(new PropertyChangeEvent(AbstractAsyncTableRendering.this, IBasicPropertyConstants.P_TEXT, null, fLabel));
1893                return Status.OK_STATUS;
1894            }};
1895        job.setSystem(true);
1896        job.setRule(serialByRenderingRule);
1897        job.schedule();
1898    }
1899    
1900    private String JavaDoc buildLabel(boolean showAddress) {
1901        String JavaDoc label = ""; //$NON-NLS-1$
1902
if (getMemoryBlock() instanceof IMemoryBlockExtension)
1903        {
1904            label = ((IMemoryBlockExtension)getMemoryBlock()).getExpression();
1905            
1906            if (label.startsWith("&")) //$NON-NLS-1$
1907
label = "&" + label; //$NON-NLS-1$
1908

1909            if (label == null)
1910            {
1911                label = DebugUIMessages.AbstractTableRendering_8;
1912            }
1913            
1914            try {
1915                if (showAddress && ((IMemoryBlockExtension)getMemoryBlock()).getBigBaseAddress() != null)
1916                {
1917                    label += " : 0x"; //$NON-NLS-1$
1918
label += ((IMemoryBlockExtension)getMemoryBlock()).getBigBaseAddress().toString(16).toUpperCase();
1919                }
1920            } catch (DebugException e) {
1921                // do nothing, the label will not show the address
1922
}
1923        }
1924        else
1925        {
1926            long address = getMemoryBlock().getStartAddress();
1927            label = Long.toHexString(address).toUpperCase();
1928        }
1929        
1930        String JavaDoc preName = DebugUITools.getMemoryRenderingManager().getRenderingType(getRenderingId()).getLabel();
1931        
1932        if (preName != null)
1933            label += " <" + preName + ">"; //$NON-NLS-1$ //$NON-NLS-2$
1934

1935        return decorateLabel(label);
1936    }
1937    
1938    /* Returns the label of this rendering.
1939     *
1940     * @return label of this rendering
1941     */

1942    public String JavaDoc getLabel() {
1943        
1944        if (fLabel == null)
1945        {
1946            fLabel = DebugUIMessages.AbstractAsyncTableRendering_1;
1947            updateRenderingLabel(isVisible());
1948        }
1949        
1950        return fLabel;
1951    }
1952    
1953    /* (non-Javadoc)
1954     * @see org.eclipse.core.runtime.PlatformObject#getAdapter(java.lang.Class)
1955     */

1956    public Object JavaDoc getAdapter(Class JavaDoc adapter) {
1957        
1958        if (adapter == IColorProvider.class)
1959            return getColorProviderAdapter();
1960        
1961        if (adapter == ILabelProvider.class)
1962            return getLabelProviderAdapter();
1963        
1964        if (adapter == IFontProvider.class)
1965            return getFontProviderAdapter();
1966        
1967        if (adapter == IModelChangedListener.class)
1968        {
1969            return fModelChangedListener;
1970        }
1971        
1972        if (adapter == IWorkbenchAdapter.class)
1973        {
1974            // needed workbench adapter to fill the title of property page
1975
if (fWorkbenchAdapter == null) {
1976                fWorkbenchAdapter = new IWorkbenchAdapter() {
1977                    public Object JavaDoc[] getChildren(Object JavaDoc o) {
1978                        return new Object JavaDoc[0];
1979                    }
1980    
1981                    public ImageDescriptor getImageDescriptor(Object JavaDoc object) {
1982                        return null;
1983                    }
1984    
1985                    public String JavaDoc getLabel(Object JavaDoc o) {
1986                        return AbstractAsyncTableRendering.this.getLabel();
1987                    }
1988    
1989                    public Object JavaDoc getParent(Object JavaDoc o) {
1990                        return null;
1991                    }
1992                };
1993            }
1994            return fWorkbenchAdapter;
1995        }
1996        
1997        if (adapter == TableRenderingContentDescriptor.class)
1998            return getContentDescriptor();
1999        
2000        return super.getAdapter(adapter);
2001    }
2002    
2003    /**
2004     * Returns the number of characters a byte will convert to
2005     * or -1 if unknown.
2006     *
2007     * @return the number of characters a byte will convert to
2008     * or -1 if unknown
2009     */

2010    public int getNumCharsPerByte()
2011    {
2012        return -1;
2013    }
2014    
2015    /**
2016     * Create actions for this rendering
2017     */

2018    protected void createActions() {
2019        
2020        fCopyToClipboardAction = new AsyncCopyTableRenderingAction(this, fTableViewer);
2021        fGoToAddressAction = new RenderingGoToAddressAction(this);
2022        fResetMemoryBlockAction = new ResetToBaseAddressAction(this);
2023        
2024        fPrintViewTabAction = new AsyncPrintTableRenderingAction(this, fTableViewer);
2025        
2026        fFormatRenderingAction = new FormatTableRenderingAction(this);
2027        fReformatAction = new ReformatAction(this);
2028        fToggleAddressColumnAction = new ToggleAddressColumnAction();
2029        
2030        IMemoryRenderingSite site = getMemoryRenderingContainer().getMemoryRenderingSite();
2031        if (site.getSite().getSelectionProvider() != null)
2032        {
2033            fPropertiesDialogAction = new PropertyDialogAction(site.getSite(),site.getSite().getSelectionProvider());
2034        }
2035        
2036        fNextAction = new NextPageAction();
2037        fPrevAction = new PrevPageAction();
2038    }
2039    
2040    /**
2041     * Returns the currently selected address in this rendering.
2042     *
2043     * @return the currently selected address in this rendering
2044     */

2045    public BigInteger JavaDoc getSelectedAddress() {
2046        Object JavaDoc key = fTableViewer.getSelectionKey();
2047        
2048        if (key != null && key instanceof BigInteger JavaDoc)
2049            return (BigInteger JavaDoc)key;
2050        
2051        return null;
2052    }
2053
2054    /**
2055     * Returns the currently selected content in this rendering as MemoryByte.
2056     *
2057     * @return the currently selected content in array of MemoryByte.
2058     * Returns an empty array if the selected address is out of buffered range.
2059     */

2060    public MemoryByte[] getSelectedAsBytes()
2061    {
2062        if (getSelectedAddress() == null)
2063            return new MemoryByte[0];
2064        
2065        Object JavaDoc key = fTableViewer.getSelectionKey();
2066        AbstractVirtualContentTableModel model = fTableViewer.getVirtualContentModel();
2067        
2068        if (model != null)
2069        {
2070            model = (AbstractVirtualContentTableModel)fTableViewer.getModel();
2071            int row = model.indexOfKey(key);
2072            Object JavaDoc element = model.getElement(row);
2073            int col = model.columnOf(element, key);
2074        
2075            // check precondition
2076
if (col <= 0 || col > getBytesPerLine()/getBytesPerColumn())
2077            {
2078                return new MemoryByte[0];
2079            }
2080            
2081            if (!(element instanceof MemorySegment))
2082                return new MemoryByte[0];
2083            
2084            MemorySegment line = (MemorySegment)element;
2085            int offset = (col-1)*(getAddressableUnitPerColumn()*getAddressableSize());
2086            
2087            // make a copy of the bytes to ensure that data cannot be changed
2088
// by caller
2089
MemoryByte[] bytes = line.getBytes(offset, getAddressableUnitPerColumn()*getAddressableSize());
2090            MemoryByte[] retBytes = new MemoryByte[bytes.length];
2091            
2092            System.arraycopy(bytes, 0, retBytes, 0, bytes.length);
2093            return retBytes;
2094        }
2095        return new MemoryByte[0];
2096    }
2097
2098    /**
2099     * Returns the currently selected content in this rendering as a String.
2100     *
2101     * @return the currently selected content in this rendering
2102     */

2103    public String JavaDoc getSelectedAsString() {
2104
2105        if (getSelectedAddress() == null)
2106            return ""; //$NON-NLS-1$
2107

2108        MemoryByte[] bytes = getSelectedAsBytes();
2109        if (bytes.length > 0)
2110        {
2111            return getString(this.getRenderingId(), getSelectedAddress(), bytes);
2112        }
2113        else
2114            return ""; //$NON-NLS-1$
2115

2116    }
2117
2118    /**
2119     * Moves the cursor to the specified address.
2120     * Will load more memory if the address is not currently visible.
2121     *
2122     * @param address address to position cursor at
2123     * @throws DebugException if an exception occurs
2124     */

2125    public void goToAddress(BigInteger JavaDoc address) throws DebugException {
2126        
2127        if (fTableViewer.getVirtualContentModel() == null)
2128            return;
2129        
2130        int i = fTableViewer.getVirtualContentModel().indexOfKey(address);
2131
2132        if (i >= 0)
2133        {
2134            // address is within range, set cursor and reveal
2135
fTableViewer.setSelection(address);
2136            updateSyncTopAddress(getTopVisibleAddress());
2137            updateSyncSelectedAddress(address);
2138        }
2139        else
2140        {
2141            // if not extended memory block
2142
// do not allow user to go to an address that's out of range
2143
if (!(getMemoryBlock() instanceof IMemoryBlockExtension))
2144            {
2145                Status stat = new Status(
2146                 IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(),
2147                 DebugException.NOT_SUPPORTED, DebugUIMessages.AbstractTableRendering_11, null
2148                );
2149                DebugException e = new DebugException(stat);
2150                throw e;
2151            }
2152
2153            BigInteger JavaDoc startAdd = fContentDescriptor.getStartAddress();
2154            BigInteger JavaDoc endAdd = fContentDescriptor.getEndAddress();
2155            
2156            if (address.compareTo(startAdd) < 0 ||
2157                address.compareTo(endAdd) > 0)
2158            {
2159                Status stat = new Status(
2160                 IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(),
2161                 DebugException.NOT_SUPPORTED, DebugUIMessages.AbstractTableRendering_11, null
2162                );
2163                DebugException e = new DebugException(stat);
2164                throw e;
2165            }
2166    
2167            // load at the address
2168
fTableViewer.setSelection(address);
2169            reloadTable(address);
2170    
2171            updateSyncSelectedAddress(address);
2172
2173            if (!isDynamicLoad())
2174            {
2175                updateSyncPageStartAddress(address);
2176            }
2177            
2178            updateSyncTopAddress(address);
2179        }
2180    }
2181    
2182    /**
2183     * Refresh the table viewer with the current top visible address.
2184     * Update labels in the memory rendering.
2185     */

2186    public void refresh() {
2187        fTableViewer.refresh();
2188    }
2189
2190    
2191    /**
2192     * Resize column to the preferred size.
2193     */

2194    public void resizeColumnsToPreferredSize() {
2195        fTableViewer.resizeColumnsToPreferredSize();
2196        if (!fIsShowAddressColumn)
2197        {
2198            final TableColumn column = fTableViewer.getTable().getColumn(0);
2199            column.addControlListener(new ControlListener() {
2200
2201                public void controlMoved(ControlEvent e) {
2202                }
2203
2204                public void controlResized(ControlEvent e) {
2205                    column.removeControlListener(this);
2206                    column.setWidth(0);
2207                }});
2208        }
2209    }
2210
2211    /**
2212     * Updates labels of this rendering.
2213     */

2214    public void updateLabels()
2215    {
2216        UIJob job = new UIJob("updateLabels"){ //$NON-NLS-1$
2217

2218            public IStatus runInUIThread(IProgressMonitor monitor) {
2219                            
2220                // do not handle if the rendering is already disposed
2221
if (fPageBook.isDisposed())
2222                    return Status.OK_STATUS;
2223                
2224                // update tab labels
2225
updateRenderingLabel(true);
2226                
2227                if (fTableViewer != null)
2228                {
2229                    // update column labels
2230
setColumnHeadings();
2231                    
2232                    // rebuild cache and force labels to be refreshed
2233
fTableViewer.formatViewer();
2234                }
2235                return Status.OK_STATUS;
2236            }};
2237        job.setSystem(true);
2238        job.schedule();
2239    }
2240    
2241    /**
2242     * Fills the context menu for this rendering
2243     *
2244     * @param menu menu to fill
2245     */

2246    protected void fillContextMenu(IMenuManager menu) {
2247        
2248        menu.add(new Separator(EMPTY_MEMORY_GROUP));
2249        menu.add(new Separator());
2250        menu.add(fResetMemoryBlockAction);
2251        menu.add(fGoToAddressAction);
2252        menu.add(new Separator(EMPTY_NAVIGATION_GROUP));
2253        
2254        menu.add(new Separator());
2255        menu.add(fFormatRenderingAction);
2256
2257        if (!isDynamicLoad() && getMemoryBlock() instanceof IMemoryBlockExtension)
2258        {
2259            menu.add(new Separator());
2260            menu.add(fPrevAction);
2261            menu.add(fNextAction);
2262            menu.add(new Separator(EMPTY_NON_AUTO_LOAD_GROUP));
2263        }
2264        
2265        menu.add(new Separator());
2266        menu.add(fReformatAction);
2267        menu.add(fToggleAddressColumnAction);
2268        menu.add(new Separator());
2269        menu.add(fCopyToClipboardAction);
2270        menu.add(fPrintViewTabAction);
2271        if (fPropertiesDialogAction != null)
2272        {
2273            menu.add(new Separator());
2274            menu.add(fPropertiesDialogAction);
2275            menu.add(new Separator(EMPTY_PROPERTY_GROUP));
2276        }
2277        
2278        menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
2279    }
2280    
2281    private int getPageSizeInUnits()
2282    {
2283        return fPageSize * getAddressableUnitPerLine();
2284    }
2285    
2286    private void getPageSizeFromPreference()
2287    {
2288        fPageSize = DebugUIPlugin.getDefault().getPreferenceStore().getInt(IDebugPreferenceConstants.PREF_TABLE_RENDERING_PAGE_SIZE);
2289    }
2290    
2291    private void getPreBufferSizeFromPreference()
2292    {
2293        fPreBufferSize = DebugUIPlugin.getDefault().getPreferenceStore().getInt(IDebugPreferenceConstants.PREF_TABLE_RENDERING_PRE_BUFFER_SIZE);
2294    }
2295    
2296    private void getPostBufferSizeFromPreference()
2297    {
2298        fPostBufferSize = DebugUIPlugin.getDefault().getPreferenceStore().getInt(IDebugPreferenceConstants.PREF_TABLE_RENDERING_POST_BUFFER_SIZE);
2299    }
2300    
2301    private void updateDynamicLoadProperty() {
2302        
2303        boolean value = DebugUIPlugin
2304                .getDefault()
2305                .getPreferenceStore()
2306                .getBoolean(IDebugPreferenceConstants.PREF_DYNAMIC_LOAD_MEM);
2307        
2308        if (value != isDynamicLoad())
2309        {
2310            setDynamicLoad(value);
2311        
2312            if (!fIsDisposed) {
2313                if (isDynamicLoad()) {
2314                    fContentDescriptor.setPostBuffer(getPostBufferSize());
2315                    fContentDescriptor.setPreBuffer(getPreBufferSize());
2316                    fContentDescriptor.setNumLines(getNumberOfVisibleLines());
2317    
2318                } else {
2319                    fContentDescriptor.setPostBuffer(0);
2320                    fContentDescriptor.setPreBuffer(0);
2321                    fContentDescriptor.setNumLines(fPageSize);
2322                }
2323            }
2324        }
2325    }
2326    
2327    private void getDynamicLoadFromPreference()
2328    {
2329        setDynamicLoad(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugPreferenceConstants.PREF_DYNAMIC_LOAD_MEM));
2330    }
2331    
2332    private boolean isDynamicLoad()
2333    {
2334        return fContentDescriptor.isDynamicLoad();
2335    }
2336    
2337    private int getPageSize()
2338    {
2339        return fPageSize;
2340    }
2341    
2342    private int getNumLinesToLoad() {
2343        int numberOfLines = -1;
2344        
2345        if (isDynamicLoad())
2346            numberOfLines = getNumberOfVisibleLines();
2347        else
2348            numberOfLines = getPageSize();
2349        
2350        return numberOfLines;
2351    }
2352    
2353    private void setDynamicLoad(boolean load)
2354    {
2355        fContentDescriptor.setDynamicLoad(load);
2356    }
2357    
2358    private void handlePageStartAddressChanged(BigInteger JavaDoc address)
2359    {
2360        // do not handle if in dynamic mode
2361
if (isDynamicLoad())
2362            return;
2363        
2364        if (!(getMemoryBlock() instanceof IMemoryBlockExtension))
2365            return;
2366        
2367        // do not handle event if the base address of the memory
2368
// block has changed, wait for debug event to update to
2369
// new location
2370
if (isMemoryBlockBaseAddressChanged())
2371            return;
2372
2373        if(fTableViewer.getKey(0).equals(address))
2374            return;
2375    
2376        BigInteger JavaDoc start = fContentDescriptor.getStartAddress();
2377        BigInteger JavaDoc end = fContentDescriptor.getEndAddress();
2378        
2379        // smaller than start address, load at start address
2380
if (address.compareTo(start) < 0)
2381        {
2382            if (isAtTopLimit())
2383                return;
2384            
2385            address = start;
2386        }
2387        
2388        // bigger than end address, no need to load, already at top
2389
if (address.compareTo(end) > 0)
2390        {
2391            if (isAtBottomLimit())
2392                return;
2393            
2394            address = end.subtract(BigInteger.valueOf(getPageSizeInUnits()));
2395        }
2396        
2397        fContentDescriptor.setLoadAddress(address);
2398        final BigInteger JavaDoc finaladdress = address;
2399        Runnable JavaDoc runnable = new Runnable JavaDoc() {
2400            public void run() {
2401                if (fTableViewer.getTable().isDisposed())
2402                    return;
2403                
2404                fTableViewer.setTopIndex(finaladdress);
2405                refresh();
2406            }};
2407        
2408        runOnUIThread(runnable);
2409
2410        updateSyncPageStartAddress(address);
2411        updateSyncTopAddress(address);
2412    }
2413    private void handleDyanicLoadChanged() {
2414        
2415        // if currently in dynamic load mode, update page
2416
// start address
2417
BigInteger JavaDoc pageStart = getTopVisibleAddress();
2418        updateSyncPageStartAddress(pageStart);
2419        
2420        updateDynamicLoadProperty();
2421        if (isDynamicLoad())
2422        {
2423            refresh();
2424            fTableViewer.setTopIndex(pageStart);
2425        }
2426        else
2427        {
2428            handlePageStartAddressChanged(pageStart);
2429        }
2430    }
2431    
2432    /* (non-Javadoc)
2433     * @see org.eclipse.debug.ui.memory.IMemoryRendering#becomesHidden()
2434     */

2435    public void becomesHidden() {
2436        // creates new object for storing potential changes in sync properties
2437
fPendingSyncProperties = new PendingPropertyChanges();
2438        super.becomesHidden();
2439        
2440        if (getMemoryBlock() instanceof IMemoryBlockExtension)
2441            updateRenderingLabel(false);
2442    }
2443
2444    /* (non-Javadoc)
2445     * @see org.eclipse.debug.ui.memory.IMemoryRendering#becomesVisible()
2446     */

2447    public void becomesVisible() {
2448        
2449        if (!fIsCreated)
2450        {
2451            // label can still be constructed even though the rendering has not finished being
2452
// initialized
2453
updateRenderingLabel(true);
2454            super.becomesVisible();
2455            return;
2456        }
2457        
2458        // do not do anything if already visible
2459
if (isVisible() == true)
2460        {
2461            // super should always be called
2462
super.becomesVisible();
2463            return;
2464        }
2465        
2466        super.becomesVisible();
2467        
2468        if (fPendingSyncProperties != null)
2469        {
2470            // deal with format
2471
boolean format = false;
2472            int rowSize = getBytesPerLine();
2473            if (fPendingSyncProperties.getRowSize() > 0)
2474            {
2475                format = true;
2476                rowSize = fPendingSyncProperties.getRowSize();
2477            }
2478            
2479            int colSize = getBytesPerColumn();
2480            if (fPendingSyncProperties.getColumnSize() > 0)
2481            {
2482                format = true;
2483                colSize = fPendingSyncProperties.getColumnSize();
2484            }
2485            
2486            if (format)
2487                format(rowSize, colSize);
2488            
2489            BigInteger JavaDoc selectedAddress = fPendingSyncProperties.getSelectedAddress();
2490            if (selectedAddress != null)
2491                fTableViewer.setSelection(selectedAddress);
2492            
2493            updateDynamicLoadProperty();
2494            
2495            if (isDynamicLoad())
2496            {
2497                BigInteger JavaDoc topVisibleAddress = fPendingSyncProperties.getTopVisibleAddress();
2498                if (topVisibleAddress != null)
2499                {
2500                    fContentDescriptor.setLoadAddress(topVisibleAddress);
2501                    fTableViewer.setTopIndex(topVisibleAddress);
2502                }
2503            }
2504            else if (!(getMemoryBlock() instanceof IMemoryBlockExtension))
2505            {
2506                BigInteger JavaDoc topVisibleAddress = fPendingSyncProperties.getTopVisibleAddress();
2507                if (topVisibleAddress != null)
2508                    fTableViewer.setTopIndex(topVisibleAddress);
2509            }
2510            else
2511            {
2512                if (fPendingSyncProperties.getPageSize() > 0)
2513                {
2514                    fPageSize = fPendingSyncProperties.getPageSize();
2515                    fContentDescriptor.setNumLines(fPageSize);
2516                }
2517                
2518                BigInteger JavaDoc pageStartAddress = fPendingSyncProperties.getPageStartAddress();
2519                if (pageStartAddress != null)
2520                    fContentDescriptor.setLoadAddress(pageStartAddress);
2521                
2522                fTableViewer.setTopIndex(pageStartAddress);
2523            }
2524            
2525            showTable();
2526            refresh();
2527        }
2528
2529        updateRenderingLabel(true);
2530        
2531        Job job = new Job("becomesVisible") //$NON-NLS-1$
2532
{
2533            protected IStatus run(IProgressMonitor monitor) {
2534                if (fIsDisposed)
2535                    return Status.OK_STATUS;
2536                try {
2537                    fContentDescriptor.updateContentBaseAddress();
2538                } catch (DebugException e) {
2539                    showMessage(e.getMessage());
2540                }
2541                return Status.OK_STATUS;
2542            }
2543        };
2544        job.setSystem(true);
2545        job.schedule();
2546        
2547        // discard these properties
2548
fPendingSyncProperties = null;
2549    }
2550    
2551    /**
2552     * Handle column size changed event from synchronizer
2553     * @param newColumnSize
2554     */

2555    private void columnSizeChanged(final int newColumnSize) {
2556        // ignore event if rendering is not visible
2557
if (!isVisible())
2558            return;
2559
2560        Display.getDefault().asyncExec(new Runnable JavaDoc() {
2561            public void run() {
2562                int rowSize = getBytesPerLine();
2563                if (rowSize < newColumnSize)
2564                    rowSize = newColumnSize;
2565                    
2566                format(rowSize, newColumnSize);
2567            }
2568        });
2569    }
2570    
2571    /**
2572     * @param newRowSize - new row size in number of bytes
2573     */

2574    private void rowSizeChanged(final int newRowSize)
2575    {
2576        // ignore event if rendering is not visible
2577
if (!isVisible())
2578            return;
2579        
2580        Display.getDefault().asyncExec(new Runnable JavaDoc() {
2581            public void run() {
2582                int colSize = getBytesPerColumn();
2583                if (newRowSize < colSize)
2584                    colSize = newRowSize;
2585                
2586                format(newRowSize, colSize);
2587            }
2588        });
2589    }
2590    
2591    /**
2592     * update selected address in synchronizer if update is true.
2593     */

2594    private void updateSyncSelectedAddress(BigInteger JavaDoc address) {
2595        
2596        if (!fIsCreated)
2597            return;
2598        PropertyChangeEvent event = new PropertyChangeEvent(this, AbstractAsyncTableRendering.PROPERTY_SELECTED_ADDRESS, null, address);
2599        firePropertyChangedEvent(event);
2600    }
2601    
2602    /**
2603     * update column size in synchronizer
2604     */

2605    private void updateSyncColSize() {
2606        
2607        if (!fIsCreated)
2608            return;
2609        
2610        PropertyChangeEvent event = new PropertyChangeEvent(this, AbstractAsyncTableRendering.PROPERTY_COL_SIZE, null, new Integer JavaDoc(fColumnSize));
2611        firePropertyChangedEvent(event);
2612    }
2613    
2614    /**
2615     * update column size in synchronizer
2616     */

2617    private void updateSyncRowSize() {
2618        
2619        if (!fIsCreated)
2620            return;
2621        
2622        PropertyChangeEvent event = new PropertyChangeEvent(this, AbstractAsyncTableRendering.PROPERTY_ROW_SIZE, null, new Integer JavaDoc(fBytePerLine));
2623        firePropertyChangedEvent(event);
2624    }
2625    
2626    /**
2627     * update top visible address in synchronizer
2628     */

2629    private void updateSyncTopAddress(BigInteger JavaDoc address) {
2630        
2631        if (!fIsCreated)
2632            return;
2633
2634        PropertyChangeEvent event = new PropertyChangeEvent(this, AbstractAsyncTableRendering.PROPERTY_TOP_ADDRESS, null, address);
2635        firePropertyChangedEvent(event);
2636    }
2637    
2638    private void updateSyncPageStartAddress(BigInteger JavaDoc address) {
2639    
2640        if (!fIsCreated)
2641            return;
2642        
2643        if (isMemoryBlockBaseAddressChanged())
2644            return;
2645        
2646        PropertyChangeEvent event = new PropertyChangeEvent(this, IInternalDebugUIConstants.PROPERTY_PAGE_START_ADDRESS, null, address);
2647        firePropertyChangedEvent(event);
2648    }
2649    
2650    /**
2651     * Returns the color provider for this rendering's memory block or
2652     * <code>null</code> if none.
2653     * <p>
2654     * By default a color provider is obtained by asking this rendering's
2655     * memory block for its {@link IColorProvider} adapter. When the color
2656     * provider is queried for color information, it is provided with a
2657     * {@link MemoryRenderingElement} as an argument.
2658     * </p>
2659     * @return the color provider for this rendering's memory block,
2660     * or <code>null</code>
2661     */

2662    protected IColorProvider getColorProviderAdapter()
2663    {
2664        return (IColorProvider)getMemoryBlock().getAdapter(IColorProvider.class);
2665    }
2666    
2667    /**
2668     * Returns the label provider for this rendering's memory block or
2669     * <code>null</code> if none.
2670     * <p>
2671     * By default a label provider is obtained by asking this rendering's
2672     * memory block for its {@link ILabelProvider} adapter. When the label
2673     * provider is queried for label information, it is provided with a
2674     * {@link MemoryRenderingElement} as an argument.
2675     * </p>
2676     * @return the label provider for this rendering's memory block,
2677     * or <code>null</code>
2678     */

2679    protected ILabelProvider getLabelProviderAdapter()
2680    {
2681        return (ILabelProvider)getMemoryBlock().getAdapter(ILabelProvider.class);
2682    }
2683    
2684    /**
2685     * Returns the font provider for this rendering's memory block or
2686     * <code>null</code> if none.
2687     * <p>
2688     * By default a font provider is obtained by asking this rendering's
2689     * memory block for its {@link IFontProvider} adapter. When the font
2690     * provider is queried for font information, it is provided with a
2691     * {@link MemoryRenderingElement} as an argument.
2692     * </p>
2693     * @return the font provider for this rendering's memory block,
2694     * or <code>null</code>
2695     */

2696    protected IFontProvider getFontProviderAdapter()
2697    {
2698        return (IFontProvider)getMemoryBlock().getAdapter(IFontProvider.class);
2699    }
2700    
2701    /**
2702     * Returns the table presentation for this rendering's memory block or
2703     * <code>null</code> if none.
2704     * <p>
2705     * By default a table presentation is obtained by asking this rendering's
2706     * memory block for its {@link IMemoryBlockTablePresentation} adapter.
2707     * </p>
2708     * @return the table presentation for this rendering's memory block,
2709     * or <code>null</code>
2710     */

2711    protected IMemoryBlockTablePresentation getTablePresentationAdapter()
2712    {
2713        return (IMemoryBlockTablePresentation)getMemoryBlock().getAdapter(IMemoryBlockTablePresentation.class);
2714    }
2715    
2716    /**
2717     * Setup the viewer so it supports hovers to show the offset of each field
2718     */

2719    private void createToolTip() {
2720        
2721        fToolTipShell = new Shell(DebugUIPlugin.getShell(), SWT.ON_TOP | SWT.RESIZE );
2722        GridLayout gridLayout = new GridLayout();
2723        gridLayout.numColumns = 1;
2724        gridLayout.marginWidth = 2;
2725        gridLayout.marginHeight = 0;
2726        fToolTipShell.setLayout(gridLayout);
2727        fToolTipShell.setBackground(fTableViewer.getTable().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
2728        
2729        final Control toolTipControl = createToolTipControl(fToolTipShell);
2730        
2731        if (toolTipControl == null)
2732        {
2733            // if client decide not to use tooltip support
2734
fToolTipShell.dispose();
2735            return;
2736        }
2737        
2738        MouseTrackAdapter listener = new MouseTrackAdapter(){
2739            
2740            private TableItem fTooltipItem = null;
2741            private int fCol = -1;
2742            
2743            public void mouseExit(MouseEvent e){
2744                
2745                if (!fToolTipShell.isDisposed())
2746                    fToolTipShell.setVisible(false);
2747                fTooltipItem = null;
2748            }
2749            
2750            public void mouseHover(MouseEvent e){
2751                
2752                Point hoverPoint = new Point(e.x, e.y);
2753                Control control = null;
2754                
2755                if (e.widget instanceof Control)
2756                    control = (Control)e.widget;
2757                
2758                if (control == null)
2759                    return;
2760                
2761                hoverPoint = control.toDisplay(hoverPoint);
2762                TableItem item = getItem(hoverPoint);
2763                int column = getColumn(hoverPoint);
2764                
2765                //Only if there is a change in hover
2766
if(this.fTooltipItem != item || fCol != column){
2767                    
2768                    //Keep Track of the latest hover
2769
fTooltipItem = item;
2770                    fCol = column;
2771                    
2772                    if(item != null){
2773                        toolTipAboutToShow(toolTipControl, fTooltipItem, column);
2774                        
2775                        //Setting location of the tooltip
2776
Rectangle shellBounds = fToolTipShell.getBounds();
2777                        shellBounds.x = hoverPoint.x;
2778                        shellBounds.y = hoverPoint.y + item.getBounds(0).height;
2779                        
2780                        fToolTipShell.setBounds(shellBounds);
2781                        fToolTipShell.pack();
2782                        
2783                        fToolTipShell.setVisible(true);
2784                    }
2785                    else {
2786                        fToolTipShell.setVisible(false);
2787                    }
2788                }
2789            }
2790        };
2791        
2792        fTableViewer.getTable().addMouseTrackListener(listener);
2793        fTableViewer.getCursor().addMouseTrackListener(listener);
2794    }
2795    
2796    /**
2797     * Creates the control used to display tool tips for cells in this table. By default
2798     * a label is used to display the address of the cell. Clients may override this
2799     * method to create custom tooltip controls.
2800     * <p>
2801     * Also see the methods <code>getToolTipText(...)</code> and
2802     * <code>toolTipAboutToShow(...)</code>.
2803     * </p>
2804     * @param composite parent for the tooltip control
2805     * @return the tooltip control to be displayed
2806     * @since 3.2
2807     */

2808    protected Control createToolTipControl(Composite composite) {
2809        Control fToolTipLabel = new Label(composite, SWT.NONE);
2810        fToolTipLabel.setForeground(fTableViewer.getTable().getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
2811        fToolTipLabel.setBackground(fTableViewer.getTable().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
2812        fToolTipLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL |
2813                GridData.VERTICAL_ALIGN_CENTER));
2814        return fToolTipLabel;
2815    }
2816    
2817    /**
2818     * Bug with table widget,BUG 113015, the widget is not able to return the correct
2819     * table item if SWT.FULL_SELECTION is not on when the table is created.
2820     * Created the following function to work around the problem.
2821     * We can remove this method when the bug is fixed.
2822     * @param point
2823     * @return the table item where the point is located, return null if the item cannot be located.
2824     */

2825    private TableItem getItem(Point point)
2826    {
2827        TableItem[] items = fTableViewer.getTable().getItems();
2828        for (int i=0; i<items.length; i++)
2829        {
2830            TableItem item = items[i];
2831            if (item.getData() != null)
2832            {
2833                Point start = new Point(item.getBounds(0).x, item.getBounds(0).y);
2834                start = fTableViewer.getTable().toDisplay(start);
2835                Point end = new Point(start.x + item.getBounds(0).width, start.y + item.getBounds(0).height);
2836                
2837                if (start.y < point.y && point.y < end.y)
2838                    return item;
2839            }
2840        }
2841        return null;
2842    }
2843    
2844    /**
2845     * Method for figuring out which column the point is located.
2846     * @param point
2847     * @return the column index where the point is located, return -1 if column is not found.
2848     */

2849    private int getColumn(Point point)
2850    {
2851        int colCnt = fTableViewer.getTable().getColumnCount();
2852        
2853        TableItem item = null;
2854        for (int i=0; i<fTableViewer.getTable().getItemCount(); i++)
2855        {
2856            item = fTableViewer.getTable().getItem(i);
2857            if (item.getData() != null)
2858                break;
2859        }
2860        
2861        if (item != null)
2862        {
2863            for (int i=0; i<colCnt; i++)
2864            {
2865                Point start = new Point(item.getBounds(i).x, item.getBounds(i).y);
2866                start = fTableViewer.getTable().toDisplay(start);
2867                Point end = new Point(start.x + item.getBounds(i).width, start.y + item.getBounds(i).height);
2868                
2869                if (start.x < point.x && end.x > point.x)
2870                    return i;
2871            }
2872        }
2873        return -1;
2874    }
2875    
2876    /**
2877     * Called when the tool tip is about to show in this rendering.
2878     * Clients who overrides <code>createTooltipControl</code> may need to
2879     * also override this method to ensure that the tooltip shows up properly
2880     * in their customized control.
2881     * <p>
2882     * By default a text tooltip is displayed, and the contents for the tooltip
2883     * are generated by the <code>getToolTipText(...)</code> method.
2884     * </p>
2885     * @param toolTipControl - the control for displaying the tooltip
2886     * @param item - the table item where the mouse is pointing.
2887     * @param col - the column at which the mouse is pointing.
2888     * @since 3.2
2889     */

2890    protected void toolTipAboutToShow(Control toolTipControl, TableItem item,
2891            int col) {
2892        if (toolTipControl instanceof Label) {
2893            Object JavaDoc address = fTableViewer.getKey(fTableViewer.getTable().indexOf(item), col);
2894            if (address != null && address instanceof BigInteger JavaDoc) {
2895                Object JavaDoc data = item.getData();
2896                if (data instanceof MemorySegment) {
2897                    MemorySegment line = (MemorySegment) data;
2898
2899                    if (col > 0) {
2900                        int start = (col - 1) * getBytesPerColumn();
2901                        int end = start + getBytesPerColumn();
2902                        MemoryByte[] bytes = line.getBytes(start, end);
2903
2904                        String JavaDoc str = getToolTipText((BigInteger JavaDoc)address, bytes);
2905
2906                        if (str != null)
2907                            ((Label) toolTipControl).setText(str);
2908                    } else {
2909                        String JavaDoc str = getToolTipText((BigInteger JavaDoc)address,
2910                                new MemoryByte[] {});
2911
2912                        if (str != null)
2913                            ((Label) toolTipControl).setText(str);
2914                    }
2915                }
2916            }
2917        }
2918    }
2919    
2920    /**
2921     * Returns the text to display in a tool tip at the specified address
2922     * for the specified bytes. By default the address of the bytes is displayed.
2923     * Subclasses may override.
2924     *
2925     * @param address address of cell that tool tip is displayed for
2926     * @param bytes the bytes in the cell
2927     * @return the tooltip text for the memory bytes located at the specified
2928     * address
2929     * @since 3.2
2930     */

2931    protected String JavaDoc getToolTipText(BigInteger JavaDoc address, MemoryByte[] bytes)
2932    {
2933        StringBuffer JavaDoc buf = new StringBuffer JavaDoc("0x"); //$NON-NLS-1$
2934
buf.append(address.toString(16).toUpperCase());
2935        
2936        return buf.toString();
2937    }
2938    
2939    private void setColumnHeadings()
2940    {
2941        String JavaDoc[] columnLabels = new String JavaDoc[0];
2942        
2943        IMemoryBlockTablePresentation presentation = getTablePresentationAdapter();
2944        if (presentation != null)
2945        {
2946            columnLabels = presentation.getColumnLabels(getMemoryBlock(), getBytesPerLine(), getBytesPerLine()/getBytesPerColumn());
2947        }
2948        
2949        // check that column labels returned are not null
2950
if (columnLabels == null)
2951            columnLabels = new String JavaDoc[0];
2952        
2953        int numByteColumns = fBytePerLine/fColumnSize;
2954        
2955        TableColumn[] columns = fTableViewer.getTable().getColumns();
2956        
2957        int j=0;
2958        for (int i=1; i<columns.length-1; i++)
2959        {
2960            // if the number of column labels returned is correct
2961
// use supplied column labels
2962
if (columnLabels.length == numByteColumns)
2963            {
2964                columns[i].setText(columnLabels[j]);
2965                j++;
2966            }
2967            else
2968            {
2969                // otherwise, use default
2970
int addressableUnit = getAddressableUnitPerColumn();
2971                if (addressableUnit >= 4)
2972                {
2973                    columns[i].setText(Integer.toHexString(j*addressableUnit).toUpperCase() +
2974                            " - " + Integer.toHexString(j*addressableUnit+addressableUnit-1).toUpperCase()); //$NON-NLS-1$
2975
}
2976                else
2977                {
2978                    columns[i].setText(Integer.toHexString(j*addressableUnit).toUpperCase());
2979                }
2980                j++;
2981            }
2982        }
2983    }
2984    
2985    /**
2986     *
2987     * Return this rendering's viewer
2988     * @return this rendering's viewer
2989     */

2990    public StructuredViewer getViewer()
2991    {
2992        return fTableViewer;
2993    }
2994    
2995    private boolean isMemoryBlockBaseAddressChanged()
2996    {
2997        try {
2998            BigInteger JavaDoc address = getMemoryBlockBaseAddress();
2999            BigInteger JavaDoc oldBaseAddress = fContentDescriptor.getContentBaseAddress();
3000            if (!oldBaseAddress.equals(address))
3001                return true;
3002        } catch (DebugException e) {
3003            // fail silently
3004
}
3005        return false;
3006    }
3007    
3008    /**
3009     * @param topVisibleAddress
3010     */

3011    private void createContentDescriptor(final BigInteger JavaDoc topVisibleAddress) {
3012        fContentDescriptor = new TableRenderingContentDescriptor(AbstractAsyncTableRendering.this);
3013        fContentDescriptor.setPostBuffer(getPostBufferSize());
3014        fContentDescriptor.setPreBuffer(getPreBufferSize());
3015        fContentDescriptor.setLoadAddress(topVisibleAddress);
3016        try {
3017            fContentDescriptor.updateContentBaseAddress();
3018            
3019        } catch (DebugException e) {
3020            fError = true;
3021            showMessage(e.getMessage());
3022        }
3023        
3024        fContentDescriptor.setAddressableSize(getAddressableSize());
3025            
3026        try {
3027            int addressSize = 4;
3028            if (getMemoryBlock() instanceof IMemoryBlockExtension)
3029            {
3030                IMemoryBlockExtension extMb = (IMemoryBlockExtension)getMemoryBlock();
3031                addressSize = extMb.getAddressSize();
3032                
3033                if (addressSize <= 0)
3034                {
3035                    DebugUIPlugin.logErrorMessage("Invalid address Size: " + addressSize); //$NON-NLS-1$
3036
addressSize = 4;
3037                }
3038                fContentDescriptor.setAddressSize(addressSize);
3039            }
3040            fContentDescriptor.setAddressSize(addressSize);
3041        } catch (DebugException e) {
3042            fError = true;
3043            showMessage(e.getMessage());
3044        } finally {
3045            if (fContentDescriptor.getAddressSize() <= 0)
3046                fContentDescriptor.setAddressSize(4);
3047        }
3048    }
3049    
3050    /**
3051     * Return the number of lines to be bufferred before the top visible line of the memory rendering
3052     * @return number of lines to be buffered before the top visible line in the memory rendering
3053     */

3054    private int getPreBufferSize()
3055    {
3056        if (fPreBufferSize < 0)
3057            getPreBufferSizeFromPreference();
3058        
3059        return fPreBufferSize;
3060    }
3061    
3062    /**
3063     * Returns the number of lines to be bufferred after the last visible line in the memory rendering
3064     * @return the number of lines to be bufferred after the last visible line in the memory rendering
3065     */

3066    private int getPostBufferSize()
3067    {
3068        if (fPostBufferSize < 0)
3069            getPostBufferSizeFromPreference();
3070        
3071        return fPostBufferSize;
3072    }
3073    
3074    private TableRenderingContentDescriptor getContentDescriptor()
3075    {
3076        return fContentDescriptor;
3077    }
3078    
3079    private void createGoToAddressComposite(Composite parent)
3080    {
3081        fGoToAddressComposite = new GoToAddressComposite();
3082        fGoToAddressComposite.createControl(parent);
3083        Button button = fGoToAddressComposite.getButton(IDialogConstants.OK_ID);
3084        if (button != null)
3085        {
3086            button.addSelectionListener(new SelectionAdapter() {
3087
3088                public void widgetSelected(SelectionEvent e) {
3089                    doGoToAddress();
3090                }
3091            });
3092            
3093            button = fGoToAddressComposite.getButton(IDialogConstants.CANCEL_ID);
3094            if (button != null)
3095            {
3096                button.addSelectionListener(new SelectionAdapter() {
3097                    public void widgetSelected(SelectionEvent e) {
3098                        hideGotoAddressComposite();
3099                    }});
3100            }
3101        }
3102        
3103        fGoToAddressComposite.getExpressionWidget().addSelectionListener(new SelectionAdapter() {
3104            public void widgetDefaultSelected(SelectionEvent e) {
3105                doGoToAddress();
3106            }});
3107        
3108        fGoToAddressComposite.getExpressionWidget().addKeyListener(new KeyAdapter() {
3109
3110            public void keyPressed(KeyEvent e) {
3111                if (e.keyCode == SWT.ESC)
3112                    hideGotoAddressComposite();
3113                super.keyPressed(e);
3114            }});
3115    }
3116    
3117    private void showGoToAddressComposite() {
3118        
3119        String JavaDoc selectedStr = getSelectedAsString();
3120        Text text = fGoToAddressComposite.getExpressionWidget();
3121        text.setText(selectedStr);
3122        text.setSelection(0, text.getCharCount());
3123    
3124        double height = fGoToAddressComposite.getHeight();
3125        double canvasHeight = fSashForm.getParent().getClientArea().height;
3126        double tableHeight = canvasHeight - height;
3127        
3128        double tableWeight = (tableHeight/canvasHeight) * 100;
3129        double textWeight = (height / canvasHeight) * 100;
3130        fSashForm.setWeights(new int[]{(int)tableWeight, (int)textWeight});
3131        fSashForm.setMaximizedControl(null);
3132        
3133        fGoToAddressComposite.getExpressionWidget().setFocus();
3134    }
3135    
3136    private void hideGotoAddressComposite()
3137    {
3138        fSashForm.setMaximizedControl(fTableViewer.getControl());
3139        if (isActivated())
3140            fTableViewer.getControl().setFocus();
3141    }
3142    
3143    /**
3144     *
3145     */

3146    private void doGoToAddress() {
3147        try {
3148            BigInteger JavaDoc address = fGoToAddressComposite.getGoToAddress(fContentDescriptor.getContentBaseAddress(), getSelectedAddress());
3149            fGoToAddressAction.doGoToAddress(address.toString(16));
3150            hideGotoAddressComposite();
3151        } catch (DebugException e1) {
3152            MemoryViewUtil.openError(DebugUIMessages.GoToAddressAction_Go_to_address_failed,
3153                    DebugUIMessages.GoToAddressAction_Go_to_address_failed, e1);
3154        } catch (NumberFormatException JavaDoc e1)
3155        {
3156            MemoryViewUtil.openError(DebugUIMessages.GoToAddressAction_Go_to_address_failed,
3157                DebugUIMessages.GoToAddressAction_Address_is_invalid, e1);
3158        }
3159    }
3160    
3161    public void activated() {
3162        super.activated();
3163        
3164        fActivated = true;
3165        IWorkbench workbench = PlatformUI.getWorkbench();
3166        ICommandService commandSupport = (ICommandService)workbench.getAdapter(ICommandService.class);
3167        IContextService contextSupport = (IContextService)workbench.getAdapter(IContextService.class);
3168        
3169        if (commandSupport != null && contextSupport != null)
3170        {
3171            fContext.add(contextSupport.activateContext(ID_ASYNC_TABLE_RENDERING_CONTEXT));
3172            Command gotoCommand = commandSupport.getCommand(ID_GO_TO_ADDRESS_COMMAND);
3173
3174            if (fGoToAddressHandler == null)
3175            {
3176                fGoToAddressHandler = new AbstractHandler() {
3177                    public Object JavaDoc execute(ExecutionEvent event) throws ExecutionException {
3178                        if (fSashForm.getMaximizedControl() != null)
3179                            fGoToAddressAction.run();
3180                        else
3181                            hideGotoAddressComposite();
3182                        return null;
3183                    }};
3184            }
3185            gotoCommand.setHandler(fGoToAddressHandler);
3186            
3187            // The page up and page down actions can only be activated if the rendering
3188
// is in manual scrolling mode. We are unable to determine the scrolling mode
3189
// until the content descriptor is created. When the rendering is activated, the content
3190
// descriptor may not be created yet. In that case, we cannot activate the shortcuts here.
3191
// We will activate the shortcut after the rendering is created.
3192
if (fContentDescriptor != null && !isDynamicLoad())
3193            {
3194                activatePageActions();
3195            }
3196        }
3197    }
3198
3199    private void activatePageActions() {
3200        IWorkbench workbench = PlatformUI.getWorkbench();
3201        ICommandService commandSupport = (ICommandService)workbench.getAdapter(ICommandService.class);
3202        if (commandSupport != null)
3203        {
3204            Command nextPage = commandSupport.getCommand(ID_NEXT_PAGE_COMMAND);
3205            if (fNextPageHandler == null)
3206            {
3207                fNextPageHandler = new AbstractHandler() {
3208    
3209                    public Object JavaDoc execute(ExecutionEvent arg0)
3210                            throws ExecutionException {
3211                        fNextAction.run();
3212                        return null;
3213                    }
3214                };
3215            }
3216            nextPage.setHandler(fNextPageHandler);
3217            
3218            Command prevPage = commandSupport.getCommand(ID_PREV_PAGE_COMMAND);
3219            if (fPrevPageHandler == null)
3220            {
3221                fPrevPageHandler = new AbstractHandler() {
3222    
3223                    public Object JavaDoc execute(ExecutionEvent arg0)
3224                            throws ExecutionException {
3225                        fPrevAction.run();
3226                        return null;
3227                    }
3228                };
3229            }
3230            prevPage.setHandler(fPrevPageHandler);
3231        }
3232    }
3233
3234    public void deactivated() {
3235        
3236        fActivated = false;
3237        IWorkbench workbench = PlatformUI.getWorkbench();
3238        ICommandService commandSupport = (ICommandService)workbench.getAdapter(ICommandService.class);
3239        IContextService contextSupport = (IContextService)workbench.getAdapter(IContextService.class);
3240        
3241        if (commandSupport != null && contextSupport != null)
3242        {
3243            // remove handler
3244
Command command = commandSupport.getCommand(ID_GO_TO_ADDRESS_COMMAND);
3245            command.setHandler(null);
3246            
3247            command = commandSupport.getCommand(ID_NEXT_PAGE_COMMAND);
3248            command.setHandler(null);
3249            
3250            command = commandSupport.getCommand(ID_PREV_PAGE_COMMAND);
3251            command.setHandler(null);
3252
3253            if (fContext != null)
3254                contextSupport.deactivateContexts(fContext);
3255        }
3256        super.deactivated();
3257    }
3258    
3259    private boolean isActivated()
3260    {
3261        return fActivated;
3262    }
3263    
3264    /**
3265     * Returns text for the given memory bytes at the specified address for the specified
3266     * rendering type. This is called by the label provider for.
3267     * Subclasses must override.
3268     *
3269     * @param renderingTypeId rendering type identifier
3270     * @param address address where the bytes belong to
3271     * @param data the bytes
3272     * @return a string to represent the memory. Cannot not return <code>null</code>.
3273     * Returns a string to pad the cell if the memory cannot be converted
3274     * successfully.
3275     */

3276    abstract public String JavaDoc getString(String JavaDoc renderingTypeId, BigInteger JavaDoc address, MemoryByte[] data);
3277    
3278    /**
3279     * Returns bytes for the given text corresponding to bytes at the given
3280     * address for the specified rendering type. This is called by the cell modifier
3281     * when modifying bytes in a memory block.
3282     * Subclasses must convert the string value to an array of bytes. The bytes will
3283     * be passed to the debug adapter for memory block modification.
3284     * Returns <code>null</code> if the bytes cannot be formatted properly.
3285     *
3286     * @param renderingTypeId rendering type identifier
3287     * @param address address the bytes begin at
3288     * @param currentValues current values of the data in bytes format
3289     * @param newValue the string to be converted to bytes
3290     * @return the bytes converted from a string
3291     */

3292    abstract public byte[] getBytes(String JavaDoc renderingTypeId, BigInteger JavaDoc address, MemoryByte[] currentValues, String JavaDoc newValue);
3293}
3294
Popular Tags