Index: plugin.properties =================================================================== RCS file: /home/eclipse/org.eclipse.debug.ui/plugin.properties,v retrieving revision 1.191 diff -u -r1.191 plugin.properties --- plugin.properties 6 May 2005 17:33:19 -0000 1.191 +++ plugin.properties 7 May 2005 22:54:47 -0000 @@ -328,8 +328,8 @@ BreakpointWorkingSet.name=Breakpoint memoryRenderingsExtensionPointName = Memory Renderings -SetDefaultColumnSizeActionName =Set Default Column Size ... SetPaddedStrActionName = Set Padded String ... +TableRenderingPrefActionName = Table Renderings Preferences... DropToFrameAction.label=Drop to Frame DropToFrameAction.tooltip=Drop to Frame Index: plugin.xml =================================================================== RCS file: /home/eclipse/org.eclipse.debug.ui/plugin.xml,v retrieving revision 1.328 diff -u -r1.328 plugin.xml --- plugin.xml 6 May 2005 17:33:16 -0000 1.328 +++ plugin.xml 7 May 2005 22:54:47 -0000 @@ -883,6 +883,14 @@ style="toggle" id="org.eclipse.debug.ui.linkrenderingpanes"/> + - 0) - bufferEnd = mbEnd; + bufferEnd = bufferEnd.add(BigInteger.valueOf(fInput.getNumLines()*addressableUnitsPerLine)); - int numLines = bufferEnd.subtract(bufferStart).divide(BigInteger.valueOf(addressableUnitsPerLine)).intValue()+1; - // get stoarage to fit the memory view tab size - getMemoryToFitTable(bufferStart, numLines, fInput.isUpdateDelta()); + if (isDynamicLoad()) + { + if (bufferStart.compareTo(mbStart) < 0) + bufferStart = mbStart; + + if (bufferEnd.compareTo(mbEnd) > 0) + bufferEnd = mbEnd; + + int numLines = bufferEnd.subtract(bufferStart).divide(BigInteger.valueOf(addressableUnitsPerLine)).intValue()+1; + // get stoarage to fit the memory view tab size + getMemoryToFitTable(bufferStart, numLines, fInput.isUpdateDelta()); + } + else + { + if (bufferStart.compareTo(mbStart) < 0) + bufferStart = mbStart; + + if (bufferEnd.compareTo(mbEnd) > 0) + { + bufferStart = mbEnd.subtract(BigInteger.valueOf((fInput.getNumLines()-1)*addressableUnitsPerLine)); + } + + int numLines = fInput.getNumLines(); + // get stoarage to fit the memory view tab size + getMemoryToFitTable(bufferStart, numLines, fInput.isUpdateDelta()); + } } /** @@ -523,6 +542,15 @@ */ protected void doHandleDebugEvent(DebugEvent event) { + if (fInput.getMemoryRendering().isVisible()) + { + // only do this if it's visible + // still need to clear content cache if the rendering + // is not visible + if (isUpdateManagedByMB()) + return; + } + // do nothing if the debug event did not come from a debug element comes from non-debug element if (!(event.getSource() instanceof IDebugElement)) return; @@ -546,7 +574,7 @@ } } - // if the suspend evnet happens from the debug target that the blocked + // if the suspend evnet happens from the debug target that the // memory block belongs to if (event.getKind() == DebugEvent.SUSPEND && src.getDebugTarget() == fInput.getMemoryBlock().getDebugTarget()) { @@ -559,7 +587,7 @@ * Update content of the view tab if the content of the memory block has changed * or if its base address has changed * Update will not be performed if the memory block has not been changed or - * if the view tab is disabled. + * if the rendering is not visible */ public void updateContent() { @@ -571,6 +599,21 @@ return; } + takeContentSnapshot(); + + //do not handle event if the rendering is not visible + if (!fInput.getMemoryRendering().isVisible()) + return; + + fInput.getMemoryRendering().refresh(); + + } + + /** + * Take a snapshot on the content, marking the lines as monitored + */ + public void takeContentSnapshot() + { // cache content before getting new ones TableRenderingLine[] lines =(TableRenderingLine[]) lineCache.toArray(new TableRenderingLine[lineCache.size()]); if (contentCache != null) @@ -598,8 +641,6 @@ // This will ensure that changes will be recomputed when user scrolls // up or down the memory view. resetDeltas(); - fInput.getMemoryRendering().refresh(); - } /** @@ -703,4 +744,43 @@ { contentCache.clear(); } + + /** + * @return if the memory block would manage its own update. + */ + private boolean isUpdateManagedByMB() + { + IMemoryBlock memoryBlock = getMemoryBlock(); + + IMemoryRenderingUpdater managedMB = null; + if (memoryBlock instanceof IMemoryRenderingUpdater) + { + managedMB = (IMemoryRenderingUpdater)memoryBlock; + } + + if (managedMB == null) + managedMB = (IMemoryRenderingUpdater)memoryBlock.getAdapter(IMemoryRenderingUpdater.class); + + // do not handle event if if the memory block wants to do its + // own update + if (managedMB != null && managedMB.supportsManagedUpdate(fInput.getMemoryRendering())) + return true; + + return false; + } + + public boolean isDynamicLoad() + { + return fDynamicLoad; + } + + private void initializeDynamicLoad() + { + fDynamicLoad = DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugPreferenceConstants.PREF_DYNAMIC_LOAD_MEM); + } + + public void setDynamicLoad(boolean dynamicLoad) + { + fDynamicLoad = dynamicLoad; + } } Index: ui/org/eclipse/debug/internal/ui/views/memory/renderings/TableRenderingPropertiesPage.java =================================================================== RCS file: /home/eclipse/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory/renderings/TableRenderingPropertiesPage.java,v retrieving revision 1.1 diff -u -r1.1 TableRenderingPropertiesPage.java --- ui/org/eclipse/debug/internal/ui/views/memory/renderings/TableRenderingPropertiesPage.java 26 Apr 2005 16:51:52 -0000 1.1 +++ ui/org/eclipse/debug/internal/ui/views/memory/renderings/TableRenderingPropertiesPage.java 7 May 2005 22:54:47 -0000 @@ -19,7 +19,7 @@ import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Label; import org.eclipse.ui.IWorkbenchPropertyPage; import org.eclipse.ui.dialogs.PropertyPage; @@ -161,9 +161,9 @@ private void addProperty(Composite composite, String labelStr, String contentStr) { - Text label = new Text(composite, SWT.READ_ONLY); + Label label = new Label(composite, SWT.NONE); label.setText(labelStr); - Text text = new Text(composite, SWT.READ_ONLY | SWT.WRAP ); + Label text = new Label(composite, SWT.WRAP ); text.setText(contentStr); } Index: ui/org/eclipse/debug/ui/memory/AbstractMemoryRendering.java =================================================================== RCS file: /home/eclipse/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/memory/AbstractMemoryRendering.java,v retrieving revision 1.10 diff -u -r1.10 AbstractMemoryRendering.java --- ui/org/eclipse/debug/ui/memory/AbstractMemoryRendering.java 26 Apr 2005 16:51:52 -0000 1.10 +++ ui/org/eclipse/debug/ui/memory/AbstractMemoryRendering.java 7 May 2005 22:54:47 -0000 @@ -79,6 +79,12 @@ */ public void dispose() { + // disconnect from memory block when rendering is disposed + if (fMemoryBlock instanceof IMemoryBlockExtension) + { + ((IMemoryBlockExtension)fMemoryBlock).disconnect(this); + } + if (fPropertyListeners != null) fPropertyListeners.clear(); } Index: ui/org/eclipse/debug/ui/memory/AbstractTableRendering.java =================================================================== RCS file: /home/eclipse/org.eclipse.debug.ui/ui/org/eclipse/debug/ui/memory/AbstractTableRendering.java,v retrieving revision 1.16 diff -u -r1.16 AbstractTableRendering.java --- ui/org/eclipse/debug/ui/memory/AbstractTableRendering.java 26 Apr 2005 16:51:52 -0000 1.16 +++ ui/org/eclipse/debug/ui/memory/AbstractTableRendering.java 7 May 2005 22:54:47 -0000 @@ -22,6 +22,7 @@ import org.eclipse.debug.internal.ui.DebugUIMessages; import org.eclipse.debug.internal.ui.DebugUIPlugin; import org.eclipse.debug.internal.ui.IInternalDebugUIConstants; +import org.eclipse.debug.internal.ui.memory.IMemoryBlockConnection; import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants; import org.eclipse.debug.internal.ui.views.memory.MemoryViewUtil; import org.eclipse.debug.internal.ui.views.memory.renderings.CopyTableRenderingToClipboardAction; @@ -183,12 +184,17 @@ private KeyAdapter fEditorKeyListener; private SelectionAdapter fCursorSelectionListener; private IWorkbenchAdapter fWorkbenchAdapter; + private IMemoryBlockConnection fConnection; private boolean fIsShowAddressColumn = true; private SelectionAdapter fScrollbarSelectionListener; private PropertyDialogAction fPropertiesAction; + private int fPageSize; + private NextPageAction fNextAction; + private PrevPageAction fPrevAction; + private class EventHandleLock { Object fOwner; @@ -252,6 +258,39 @@ } } + + private class NextPageAction extends Action + { + private NextPageAction() + { + super(); + setText(DebugUIMessages.AbstractTableRendering_4); + PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IDebugUIConstants.PLUGIN_ID + ".NextPageAction_context"); //$NON-NLS-1$ + } + + public void run() { + BigInteger address = fContentInput.getLoadAddress(); + address = address.add(BigInteger.valueOf(getPageSizeInUnits())); + handlePageStartAddressChanged(address); + } + } + + private class PrevPageAction extends Action + { + private PrevPageAction() + { + super(); + setText(DebugUIMessages.AbstractTableRendering_6); + PlatformUI.getWorkbench().getHelpSystem().setHelp(this, IDebugUIConstants.PLUGIN_ID + ".PrevPageAction_context"); //$NON-NLS-1$ + } + + public void run() { + BigInteger address = fContentInput.getLoadAddress(); + address = address.subtract(BigInteger.valueOf(getPageSizeInUnits())); + handlePageStartAddressChanged(address); + } + } + /** * Constructs a new table rendering of the specified type. * @@ -288,6 +327,11 @@ Object evtSrc = event.getSource(); + if (event.getProperty().equals(IDebugPreferenceConstants.PREF_TABLE_RENDERING_PAGE_SIZE)) { + // always update page size, only refresh if the table is visible + getPageSizeFromPreference(); + } + // do not handle event if the rendering is displaying an error if (isDisplayingError()) return; @@ -296,6 +340,20 @@ if (!isVisible()) return; + if (event.getProperty().equals(IDebugPreferenceConstants.PREF_DYNAMIC_LOAD_MEM)) { + handleDyanicLoadChanged(); + return; + } + + if (event.getProperty().equals(IDebugPreferenceConstants.PREF_TABLE_RENDERING_PAGE_SIZE)) { + if (!isDynamicLoad()) + { + // only refresh if in non-autoload mode + refresh(); + } + return; + } + if (evtSrc == this) return; @@ -324,10 +382,63 @@ { if (needMoreLines()) { - reloadTable(getTopVisibleAddress(), false); + if (isDynamicLoad()) + reloadTable(getTopVisibleAddress(), false); } topVisibleAddressChanged((BigInteger)value); } + else if (propertyName.equals(IInternalDebugUIConstants.PROPERTY_PAGE_START_ADDRESS) && value instanceof BigInteger) + { + handlePageStartAddressChanged((BigInteger)value); + } + } + + private void handleDyanicLoadChanged() { + + // if currently in dynamic load mode, update page + // start address + updateSyncPageStartAddress(); + + updateDynamicLoadProperty(); + if (isDynamicLoad()) + { + refresh(); + } + else + { + BigInteger pageStart = (BigInteger)getSynchronizedProperty(IInternalDebugUIConstants.PROPERTY_PAGE_START_ADDRESS); + if (pageStart == null) + pageStart = fTopRowAddress; + handlePageStartAddressChanged(pageStart); + } + } + + private void updateDynamicLoadProperty() { + + boolean value = DebugUIPlugin + .getDefault() + .getPreferenceStore() + .getBoolean(IDebugPreferenceConstants.PREF_DYNAMIC_LOAD_MEM); + + if (value != isDynamicLoad()) + { + fContentProvider.setDynamicLoad(value); + + if (!fIsDisposed) { + if (isDynamicLoad()) { + fContentInput.setPostBuffer(20); + fContentInput.setPreBuffer(20); + fContentInput.setDefaultBufferSize(20); + fContentInput.setNumLines(getNumberOfVisibleLines()); + + } else { + fContentInput.setPostBuffer(0); + fContentInput.setPreBuffer(0); + fContentInput.setDefaultBufferSize(0); + fContentInput.setNumLines(fPageSize); + } + } + } } /** @@ -339,6 +450,12 @@ // do not handle event if view tab is disabled if (!isVisible()) return; + + // do not handle event if the base address of the memory + // block has changed, wait for debug event to update to + // new location + if (isBaseAddressChanged()) + return; if (!address.equals(fTopRowAddress)) { @@ -406,12 +523,15 @@ } else { - reloadTable(address, false); + if (isDynamicLoad()) + reloadTable(address, false); + else + setTopIndex(table, index); } } else if ((numInBuffer-(index+getNumberOfVisibleLines())) < 3) { - if (!isAtBottomLimit()) + if (!isAtBottomLimit() && isDynamicLoad()) reloadTable(address, false); else setTopIndex(table, index); @@ -440,12 +560,89 @@ */ private void selectedAddressChanged(BigInteger value) { + // do not handle event if the base address of the memory + // block has changed, wait for debug event to update to + // new location + if (isBaseAddressChanged()) + return; + try { - goToAddress(value); + // do not handle event if the event is out of range and the + // rendering is in non-dynamic-load mode, otherwise, will + // cause rendering to continue to scroll when it shouldn't + if (isDynamicLoad()) + goToAddress(value); + else if (!isAddressOutOfRange(value)) + goToAddress(value); } catch (DebugException e) { // do nothing } } + + private void handlePageStartAddressChanged(BigInteger address) + { + // do not handle if in dynamic mode + if (isDynamicLoad()) + return; + + if (fContentInput == null) + return; + + if (!(getMemoryBlock() instanceof IMemoryBlockExtension)) + return; + + // do not handle event if the base address of the memory + // block has changed, wait for debug event to update to + // new location + if (isBaseAddressChanged()) + return; + + if(fContentProvider.getBufferTopAddress().equals(address)) + return; + + BigInteger start = fContentInput.getStartAddress(); + BigInteger end = fContentInput.getEndAddress(); + + // smaller than start address, load at start address + if (address.compareTo(start) < 0) + { + if (isAtTopLimit()) + return; + + address = start; + } + + // bigger than end address, no need to load, alread at top + if (address.compareTo(end) > 0) + { + if (isAtBottomLimit()) + return; + + address = end.subtract(BigInteger.valueOf(getPageSizeInUnits())); + } + + fContentInput.setLoadAddress(address); + refresh(); + updateSyncPageStartAddress(); + setTopIndex(fTableViewer.getTable(), 0); + fTopRowAddress = address; + updateSyncTopAddress(); + + BigInteger selectedAddress = (BigInteger)getSynchronizedProperty(AbstractTableRendering.PROPERTY_SELECTED_ADDRESS); + if (selectedAddress != null) + { + fSelectedAddress = selectedAddress; + if (!isAddressOutOfRange(fSelectedAddress)) + { + setCursorAtAddress(fSelectedAddress); + fTableCursor.setVisible(true); + } + else + { + fTableCursor.setVisible(false); + } + } + } /* (non-Javadoc) * @see org.eclipse.debug.ui.memory.IMemoryRendering#createControl(org.eclipse.swt.widgets.Composite) @@ -480,6 +677,8 @@ fTableViewer.setLabelProvider(labelProvider); fContentProvider = new TableRenderingContentProvider(); + fContentProvider.setDynamicLoad(DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugPreferenceConstants.PREF_DYNAMIC_LOAD_MEM)); + fTableViewer.setContentProvider(fContentProvider); fContentProvider.setViewer(fTableViewer); @@ -557,7 +756,7 @@ selectedAddress = BigInteger.valueOf(address); } } - fSelectedAddress = selectedAddress; + setSelectedAddress(selectedAddress); // figure out top visible address BigInteger topVisibleAddress = (BigInteger) getSynchronizedProperty(AbstractTableRendering.PROPERTY_TOP_ADDRESS); if (topVisibleAddress == null) @@ -575,7 +774,23 @@ topVisibleAddress = BigInteger.valueOf(getMemoryBlock().getStartAddress()); } } - fContentInput = new TableRenderingContentInput(this, 20, 20, 20, topVisibleAddress, getNumberOfVisibleLines(), false); + + getPageSizeFromPreference(); + if (isDynamicLoad()) + fContentInput = new TableRenderingContentInput(this, 20, 20, 20, topVisibleAddress, getNumberOfVisibleLines(), false); + else + { + BigInteger addressToLoad = topVisibleAddress; + + // check synchronization service to see if we need to sync with another rendering + Object obj = getSynchronizedProperty(IInternalDebugUIConstants.PROPERTY_PAGE_START_ADDRESS); + if (obj != null && obj instanceof BigInteger) + { + addressToLoad = (BigInteger)obj; + } + fContentInput = new TableRenderingContentInput(this, 0, 0, 0, addressToLoad, fPageSize, false); + } + fTableViewer.setInput(fContentInput); fCellModifier = new TableRenderingCellModifier(this); fTableViewer.setCellModifier(fCellModifier); @@ -637,6 +852,11 @@ DebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this); } + private void getPageSizeFromPreference() + { + fPageSize = DebugUIPlugin.getDefault().getPreferenceStore().getInt(IDebugPreferenceConstants.PREF_TABLE_RENDERING_PAGE_SIZE); + } + private void createCursor(Table table, BigInteger address) { fTableCursor = new TableCursor(table, SWT.NONE); @@ -758,7 +978,7 @@ // when the cursor is moved, the selected address is changed if (selectedAddress != null && !selectedAddress.equals(fSelectedAddress)) { - fSelectedAddress = selectedAddress; + setSelectedAddress(selectedAddress); updateSyncSelectedAddress(); } @@ -773,21 +993,25 @@ if (row < 3) { - if (!isAtTopLimit()) { - refresh(); - setCursorAtAddress(fSelectedAddress); + if (isDynamicLoad()) + { + refresh(); + setCursorAtAddress(fSelectedAddress); + } } } else if (row >= fTableViewer.getTable().getItemCount() - 3) { if (!isAtBottomLimit()) { - refresh(); - setCursorAtAddress(fSelectedAddress); + if (isDynamicLoad()) + { + refresh(); + setCursorAtAddress(fSelectedAddress); + } } - } } @@ -1190,7 +1414,6 @@ private static void setTopIndex(Table table, int index) { - MemoryViewUtil.linuxWorkAround(table); table.setTopIndex(index); } @@ -1213,6 +1436,13 @@ Object size =getSynchronizedProperty( AbstractTableRendering.PROPERTY_COL_SIZE); Object topAddress =getSynchronizedProperty( AbstractTableRendering.PROPERTY_TOP_ADDRESS); + if (!isDynamicLoad()) + { + Object pageStartAddress = getSynchronizedProperty(IInternalDebugUIConstants.PROPERTY_PAGE_START_ADDRESS); + if (pageStartAddress == null) + updateSyncPageStartAddress(); + } + // if info is available, some other view tab has already been // created // do not overwirte info int he synchronizer if that's the case @@ -1233,7 +1463,21 @@ * Get properties from synchronizer and synchronize settings */ private void synchronize() - { + { + if (!isDynamicLoad()) + { + BigInteger pageStart = (BigInteger)getSynchronizedProperty(IInternalDebugUIConstants.PROPERTY_PAGE_START_ADDRESS); + if (pageStart != null && fContentInput != null && fContentInput.getLoadAddress() != null) + { + if (!fContentInput.getLoadAddress().equals(pageStart)) + handlePageStartAddressChanged(pageStart); + } + else if (pageStart != null) + { + handlePageStartAddressChanged(pageStart); + } + } + Integer columnSize = (Integer) getSynchronizedProperty(AbstractTableRendering.PROPERTY_COL_SIZE); BigInteger selectedAddress = (BigInteger)getSynchronizedProperty(AbstractTableRendering.PROPERTY_SELECTED_ADDRESS); BigInteger topAddress = (BigInteger)getSynchronizedProperty(AbstractTableRendering.PROPERTY_TOP_ADDRESS); @@ -1315,6 +1559,31 @@ firePropertyChangedEvent(event); } + private void updateSyncPageStartAddress() { + + if (!fIsCreated) + return; + + if (isBaseAddressChanged()) + return; + + BigInteger pageStart; + if (isDynamicLoad()) + { + // if dynamic loading, the page address should be the top + // row address + pageStart = fTopRowAddress; + } + else + { + // otherwise, the address is the buffer's start address + pageStart = fContentProvider.getBufferTopAddress(); + } + + PropertyChangeEvent event = new PropertyChangeEvent(this, IInternalDebugUIConstants.PROPERTY_PAGE_START_ADDRESS, null, pageStart); + firePropertyChangedEvent(event); + } + /** * Fills the context menu for this rendering * @@ -1354,6 +1623,12 @@ } } } + if (!isDynamicLoad()) + { + menu.add(new Separator()); + menu.add(fPrevAction); + menu.add(fNextAction); + } menu.add(new Separator()); menu.add(fReformatAction); @@ -1366,6 +1641,7 @@ menu.add(new Separator()); menu.add(fPropertiesAction); } + } /** @@ -1539,11 +1815,18 @@ if (address.compareTo(fContentProvider.getContentBaseAddress()) != 0) { // get to new address - fSelectedAddress = address; + setSelectedAddress(address); updateSyncSelectedAddress(); + reloadTable(address, true); - fTopRowAddress = address; + if (!isDynamicLoad()) + { + updateSyncPageStartAddress(); + setTopIndex(fTableViewer.getTable(), 0); + } + + fTopRowAddress = getTopVisibleAddress(); updateSyncTopAddress(); fContentInput.updateContentBaseAddress(); @@ -1551,7 +1834,10 @@ else { // reload at top of table - address = getTopVisibleAddress(); + if (isDynamicLoad()) + address = getTopVisibleAddress(); + else + address = fContentInput.getLoadAddress(); reloadTable(address, true); } } catch (DebugException e) { @@ -1575,25 +1861,43 @@ { Table table = (Table)fTableViewer.getControl(); - TableRenderingContentInput input = new TableRenderingContentInput(this, fContentInput.getPreBuffer(), fContentInput.getPostBuffer(), fContentInput.getDefaultBufferSize(), topAddress, getNumberOfVisibleLines(), updateDelta); + TableRenderingContentInput input; + if (isDynamicLoad()) + input = new TableRenderingContentInput(this, fContentInput.getPreBuffer(), fContentInput.getPostBuffer(), fContentInput.getDefaultBufferSize(), topAddress, getNumberOfVisibleLines(), updateDelta); + else + input = new TableRenderingContentInput(this, fContentInput.getPreBuffer(), fContentInput.getPostBuffer(), fContentInput.getDefaultBufferSize(), topAddress, fPageSize, updateDelta); + fContentInput = input; fTableViewer.setInput(fContentInput); - if (getMemoryBlock() instanceof IMemoryBlockExtension) + if (isDynamicLoad()) { - int topIdx = findAddressIndex(topAddress); + if (getMemoryBlock() instanceof IMemoryBlockExtension) + { + int topIdx = findAddressIndex(topAddress); + + if (topIdx != -1) + { + setTopIndex(table, topIdx); + } + } - if (topIdx != -1) + // cursor needs to be refreshed after reload + if (isAddressVisible(fSelectedAddress)) + setCursorAtAddress(fSelectedAddress); + } + else + { + if (!isAddressOutOfRange(fSelectedAddress)) + { + setCursorAtAddress(fSelectedAddress); + fTableCursor.setVisible(true); + } + else { - setTopIndex(table, topIdx); + fTableCursor.setVisible(false); } } - - // cursor needs to be refreshed after reload - if (isAddressVisible(fSelectedAddress)) - setCursorAtAddress(fSelectedAddress); - - MemoryViewUtil.linuxWorkAround(fTableViewer.getTable()); } finally { @@ -1657,15 +1961,19 @@ private static int getTopVisibleIndex(Table table) { - MemoryViewUtil.linuxWorkAround(table); int index = table.getTopIndex(); TableItem item = table.getItem(index); + int cnt = table.getItemCount(); - MemoryViewUtil.linuxWorkAround(table); while (item.getBounds(0).y < 0) { index++; + if (index >= cnt) + { + index--; + break; + } item = table.getItem(index); } @@ -1778,7 +2086,7 @@ // if address is within the range, highlight if (!isAddressOutOfRange(address)) { - fSelectedAddress = address; + setSelectedAddress(address); updateSyncSelectedAddress(); setCursorAtAddress(fSelectedAddress); @@ -1817,11 +2125,15 @@ throw e; } - fSelectedAddress = address; + setSelectedAddress(address); updateSyncSelectedAddress(); - //otherwise, reload at the address - reloadTable(address,false); + reloadTable(address, false); + + if (!isDynamicLoad()) + { + updateSyncPageStartAddress(); + } // if the table is reloaded, the top address is chagned in this case fTopRowAddress = address; @@ -1900,6 +2212,9 @@ { fPropertiesAction = new PropertyDialogAction(site.getSite(),site.getSite().getSelectionProvider()); } + + fNextAction = new NextPageAction(); + fPrevAction = new PrevPageAction(); } /** @@ -1927,33 +2242,37 @@ if (getMemoryBlock() instanceof IMemoryBlockExtension) { - if (!isAddressOutOfRange(address)) + + if (isDynamicLoad()) { - Table table = fTableViewer.getTable(); - int numInBuffer = table.getItemCount(); - int index = findAddressIndex(address); - if (index < 3) + if (!isAddressOutOfRange(address)) { - if (isAtTopLimit()) + Table table = fTableViewer.getTable(); + int numInBuffer = table.getItemCount(); + int index = findAddressIndex(address); + if (index < 3) { - setTopIndex(table, index); + if (isAtTopLimit()) + { + setTopIndex(table, index); + } + else + { + reloadTable(address, false); + } } - else + else if ((numInBuffer-(index+getNumberOfVisibleLines())) < 3) { - reloadTable(address, false); + if (!isAtBottomLimit()) + reloadTable(address, false); } } - else if ((numInBuffer-(index+getNumberOfVisibleLines())) < 3) - { - if (!isAtBottomLimit()) - reloadTable(address, false); + else + { + // approaching limit, reload table + reloadTable(address, false); } } - else - { - // approaching limit, reload table - reloadTable(address, false); - } if (isAddressVisible(fSelectedAddress)) fTableCursor.setVisible(true); @@ -1971,10 +2290,10 @@ private boolean isAtTopLimit() { BigInteger startAddress = fContentInput.getStartAddress(); - startAddress = alignDoubleWordBoundary(startAddress); + startAddress = MemoryViewUtil.alignDoubleWordBoundary(startAddress); BigInteger startBufferAddress = fContentProvider.getBufferTopAddress(); - startBufferAddress = alignDoubleWordBoundary(startBufferAddress); + startBufferAddress = MemoryViewUtil.alignDoubleWordBoundary(startBufferAddress); if (startAddress.compareTo(startBufferAddress) == 0) return true; @@ -1985,10 +2304,10 @@ private boolean isAtBottomLimit() { BigInteger endAddress = fContentInput.getEndAddress(); - endAddress = alignDoubleWordBoundary(endAddress); + endAddress = MemoryViewUtil.alignDoubleWordBoundary(endAddress); BigInteger endBufferAddress = fContentProvider.getBufferEndAddress(); - endBufferAddress = alignDoubleWordBoundary(endBufferAddress); + endBufferAddress = MemoryViewUtil.alignDoubleWordBoundary(endBufferAddress); if (endAddress.compareTo(endBufferAddress) == 0) return true; @@ -1996,19 +2315,6 @@ return false; } - private BigInteger alignDoubleWordBoundary(BigInteger integer) - { - String str =integer.toString(16); - if (!str.endsWith("0")) //$NON-NLS-1$ - { - str = str.substring(0, str.length() - 1); - str += "0"; //$NON-NLS-1$ - integer = new BigInteger(str, 16); - } - - return integer; - } - private boolean needMoreLines() { if (getMemoryBlock() instanceof IMemoryBlockExtension) @@ -2501,10 +2807,15 @@ } super.becomesVisible(); - - refresh(); - synchronize(); + boolean value = DebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IDebugPreferenceConstants.PREF_DYNAMIC_LOAD_MEM); + if (value != isDynamicLoad()) + // this call will cause a reload + handleDyanicLoadChanged(); + else + refresh(); + + synchronize(); updateRenderingLabel(true); } @@ -2674,15 +2985,15 @@ public Object[] getChildren(Object o) { return new Object[0]; } - + public ImageDescriptor getImageDescriptor(Object object) { return null; } - + public String getLabel(Object o) { return getInstance().getLabel(); } - + public Object getParent(Object o) { return null; } @@ -2691,6 +3002,69 @@ return fWorkbenchAdapter; } + if (adapter == IMemoryBlockConnection.class) { + if (fConnection == null) { + fConnection = new IMemoryBlockConnection() { + public void update() { + try { + fContentProvider.takeContentSnapshot(); + if (getMemoryBlock() instanceof IMemoryBlockExtension) + { + BigInteger address = ((IMemoryBlockExtension)getMemoryBlock()).getBigBaseAddress(); + if (address.compareTo(fContentProvider.getContentBaseAddress()) != 0) + { + // get to new address + setSelectedAddress(address); + updateSyncSelectedAddress(); + fTopRowAddress = address; + fContentInput.updateContentBaseAddress(); + fContentInput.setLoadAddress(address); + } + fContentProvider.loadContentForExtendedMemoryBlock(); + } + else + fContentProvider.loadContentForSimpleMemoryBlock(); + + // update UI asynchrounously + Display display = DebugUIPlugin.getDefault().getWorkbench().getDisplay(); + display.asyncExec(new Runnable() { + public void run() { + updateLabels(); + + if (getMemoryBlock() instanceof IMemoryBlockExtension) { + int topIdx = findAddressIndex(fTopRowAddress); + if (topIdx != -1) { + setTopIndex(fTableViewer.getTable(),topIdx); + } + } + + // cursor needs to be refreshed after reload + if (isAddressVisible(fSelectedAddress)) + { + setCursorAtAddress(fSelectedAddress); + fTableCursor.setVisible(true); + fTableCursor.redraw(); + } + else + { + fTableCursor.setVisible(false); + } + + if (!isDynamicLoad()) + updateSyncPageStartAddress(); + + updateSyncTopAddress(); + } + }); + } catch (DebugException e) { + displayError(e); + } + } + }; + } + return fConnection; + } + return super.getAdapter(adapter); } @@ -2708,6 +3082,25 @@ return true; } + private boolean isBaseAddressChanged() + { + try { + IMemoryBlock mb = getMemoryBlock(); + if (mb instanceof IMemoryBlockExtension) + { + BigInteger baseAddress = ((IMemoryBlockExtension)mb).getBigBaseAddress(); + if (baseAddress != null) + { + if (!baseAddress.equals(fContentInput.getContentBaseAddress())) + return true; + } + } + } catch (DebugException e1) { + return false; + } + return false; + } + /** * Returns the color provider for this rendering's memory block or * null if none. @@ -2774,6 +3167,22 @@ return (IMemoryBlockTablePresentation)getMemoryBlock().getAdapter(IMemoryBlockTablePresentation.class); } + private boolean isDynamicLoad() + { + return fContentProvider.isDynamicLoad(); + } + + private int getPageSizeInUnits() + { + return fPageSize * getAddressableUnitPerLine(); + } + + private void setSelectedAddress(BigInteger address) + { + fSelectedAddress = address; + } + + /** * Returns text for the given memory bytes at the specified address for the specified * rendering type. This is called by the label provider for. Index: ui/org/eclipse/debug/internal/ui/memory/IMemoryBlockConnection.java =================================================================== RCS file: ui/org/eclipse/debug/internal/ui/memory/IMemoryBlockConnection.java diff -N ui/org/eclipse/debug/internal/ui/memory/IMemoryBlockConnection.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ui/org/eclipse/debug/internal/ui/memory/IMemoryBlockConnection.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.debug.internal.ui.memory; + +/** + * Represents a connection to a memory block. An IMemoryRenderingUpdater can call + * a connection to update instead of relying on a rendering to listen + * for CHANGE / SUSPEND debug event to trigger an update. + * + * This interface is EXPERIMENTAL. + * + */ +public interface IMemoryBlockConnection { + + /** + * Update the content of a memory block in a connection. + */ + public void update(); +} Index: ui/org/eclipse/debug/internal/ui/memory/IMemoryRenderingUpdater.java =================================================================== RCS file: ui/org/eclipse/debug/internal/ui/memory/IMemoryRenderingUpdater.java diff -N ui/org/eclipse/debug/internal/ui/memory/IMemoryRenderingUpdater.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ui/org/eclipse/debug/internal/ui/memory/IMemoryRenderingUpdater.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.debug.internal.ui.memory; + +import org.eclipse.debug.core.model.IMemoryBlockExtension; +import org.eclipse.debug.ui.memory.IMemoryRendering; + + +/** + * Represents an object that will manage the update of an IMemoryRendering + * based on connections. If the memory block implements this interface or returns + * an object of this type when getAdapter(...) is called, a rendering would + * call #supportsManagedUpdate to determine if it should handle and refresh + * upon a debug event. + * + * If the client wants to manage its own update, it would return true when + * #supportsManagedUpdate is called. The rendering will not get refreshed + * upon any debug events. Instead, the rendering will update when + * IMemoryBlockConnection.update is called. + * + * This interface is EXPERIMENTAL. + * + */ +public interface IMemoryRenderingUpdater extends IMemoryBlockExtension { + + /** + * @return true if the updater will manage the update of a rendering + */ + public boolean supportsManagedUpdate(IMemoryRendering rendering); + +} Index: ui/org/eclipse/debug/internal/ui/views/memory/renderings/TableRenderingPrefAction.java =================================================================== RCS file: ui/org/eclipse/debug/internal/ui/views/memory/renderings/TableRenderingPrefAction.java diff -N ui/org/eclipse/debug/internal/ui/views/memory/renderings/TableRenderingPrefAction.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ui/org/eclipse/debug/internal/ui/views/memory/renderings/TableRenderingPrefAction.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.debug.internal.ui.views.memory.renderings; + +import org.eclipse.debug.internal.ui.DebugUIMessages; +import org.eclipse.debug.internal.ui.DebugUIPlugin; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.preference.IPreferenceNode; +import org.eclipse.jface.preference.IPreferencePage; +import org.eclipse.jface.preference.PreferenceDialog; +import org.eclipse.jface.preference.PreferenceManager; +import org.eclipse.jface.preference.PreferenceNode; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.custom.BusyIndicator; +import org.eclipse.ui.IViewActionDelegate; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.actions.ActionDelegate; + +public class TableRenderingPrefAction extends ActionDelegate implements IViewActionDelegate { + + /* (non-Javadoc) + * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) + */ + public void run(IAction action) { + IPreferencePage page = new TableRenderingPreferencePage(DebugUIMessages.TableRenderingPrefAction_0); + showPreferencePage("org.eclipse.debug.ui.tableRenderingPreferencepage", page); //$NON-NLS-1$ + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IViewActionDelegate#init(org.eclipse.ui.IViewPart) + */ + public void init(IViewPart view) { + } + + protected void showPreferencePage(String id, IPreferencePage page) { + final IPreferenceNode targetNode = new PreferenceNode(id, page); + + PreferenceManager manager = new PreferenceManager(); + manager.addToRoot(targetNode); + final PreferenceDialog dialog = new PreferenceDialog(DebugUIPlugin.getShell(), manager); + final boolean [] result = new boolean[] { false }; + BusyIndicator.showWhile(DebugUIPlugin.getStandardDisplay(), new Runnable() { + public void run() { + dialog.create(); + dialog.setMessage(targetNode.getLabelText()); + result[0]= (dialog.open() == Window.OK); + } + }); + } + +} Index: ui/org/eclipse/debug/internal/ui/views/memory/renderings/TableRenderingPreferencePage.java =================================================================== RCS file: ui/org/eclipse/debug/internal/ui/views/memory/renderings/TableRenderingPreferencePage.java diff -N ui/org/eclipse/debug/internal/ui/views/memory/renderings/TableRenderingPreferencePage.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ui/org/eclipse/debug/internal/ui/views/memory/renderings/TableRenderingPreferencePage.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,221 @@ +/******************************************************************************* + * Copyright (c) 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.debug.internal.ui.views.memory.renderings; + +import org.eclipse.debug.internal.ui.DebugUIMessages; +import org.eclipse.debug.internal.ui.DebugUIPlugin; +import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.jface.preference.BooleanFieldEditor; +import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.IntegerFieldEditor; +import org.eclipse.jface.preference.PreferencePage; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.PlatformUI; + +public class TableRenderingPreferencePage extends PreferencePage implements + IPropertyChangeListener{ + + Combo fColumnSize; + private int[] fColumnSizes = new int[] {1, 2, 4, 8, 16}; + private BooleanFieldEditor fAutoLoadPref; + private IntegerFieldEditor fPageSizePref; + private Composite fBufferComposite; + + public TableRenderingPreferencePage(String title) + { + super(title); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite) + */ + protected Control createContents(Composite parent) { + PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, IDebugUIConstants.PLUGIN_ID + ".table_renderings_preference_page_context"); //$NON-NLS-1$ + + Composite composite = new Composite(parent, SWT.NONE); + + Composite columnSizeComposite = new Composite(composite, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + columnSizeComposite.setLayout(layout); + GridData data = new GridData(); + data.horizontalAlignment = SWT.FILL; + columnSizeComposite.setLayoutData(data); + + Label textLabel = new Label(columnSizeComposite, SWT.NONE); + textLabel.setText(DebugUIMessages.TableRenderingPreferencePage_0); + + fColumnSize = new Combo(columnSizeComposite, SWT.BORDER|SWT.READ_ONLY); + + GridData columnLayout= new GridData(); + fColumnSize.setLayoutData(columnLayout); + + for (int i=0; i 0) + fColumnSize.select(idx); + fAutoLoadPref.loadDefault(); + fPageSizePref.loadDefault(); + super.performDefaults(); + } + + protected IPreferenceStore doGetPreferenceStore() { + return DebugUIPlugin.getDefault().getPreferenceStore(); + } + + /** + * Adds in a spacer. + * + * @param composite the parent composite + */ + private void createSpacer(Composite composite) { + Label spacer = new Label(composite, SWT.NONE); + GridData spacerData = new GridData(); + spacerData.horizontalSpan = 1; + spacer.setLayoutData(spacerData); + } + + public void propertyChange(PropertyChangeEvent event) { + if (event.getProperty().equals(FieldEditor.VALUE)) + { + if (event.getSource().equals(fAutoLoadPref)) + { + boolean autoLoad = fAutoLoadPref.getBooleanValue(); + if (autoLoad) + { + fPageSizePref.setEnabled(false, fBufferComposite); + } + else + { + fPageSizePref.setEnabled(true, fBufferComposite); + } + validatePageSize(); + } + } + if (event.getProperty().equals(FieldEditor.VALUE)) + { + if (event.getSource().equals(fPageSizePref)) + { + validatePageSize(); + } + } + } + + private void validatePageSize() { + boolean autoLoad = fAutoLoadPref.getBooleanValue(); + try { + int bufferSize = fPageSizePref.getIntValue(); + if (!autoLoad && bufferSize < 1) + { + setValid(false); + setErrorMessage(DebugUIMessages.TableRenderingPreferencePage_3); + } + else + { + setValid(true); + setErrorMessage(null); + + } + } catch (NumberFormatException e) { + if (!autoLoad) + { + setValid(false); + setErrorMessage(DebugUIMessages.TableRenderingPreferencePage_4); + } + } + } + + public void dispose() { + + fAutoLoadPref.setPropertyChangeListener(null); + fPageSizePref.setPropertyChangeListener(null); + super.dispose(); + } + +}