mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-23 13:16:48 +08:00
Merge remote-tracking branch 'origin/GT-3269-CodeViewerVisibleAddresses'
This commit is contained in:
+14
-4
@@ -937,8 +937,8 @@ public class CodeBrowserPlugin extends Plugin
|
||||
tableFromSelectionAction.setMenuBarData(new MenuData(
|
||||
new String[] { ToolConstants.MENU_SELECTION, "Create Table From Selection" }, null,
|
||||
"SelectUtils"));
|
||||
tableFromSelectionAction.setHelpLocation(
|
||||
new HelpLocation("CodeBrowserPlugin", "Selection_Table"));
|
||||
tableFromSelectionAction
|
||||
.setHelpLocation(new HelpLocation("CodeBrowserPlugin", "Selection_Table"));
|
||||
}
|
||||
|
||||
private GhidraProgramTableModel<Address> createTableModel(CodeUnitIterator iterator,
|
||||
@@ -1013,8 +1013,8 @@ public class CodeBrowserPlugin extends Plugin
|
||||
public boolean goToField(Address a, String fieldName, int occurrence, int row, int col,
|
||||
boolean scroll) {
|
||||
|
||||
boolean result = SystemUtilities.runSwingNow(
|
||||
() -> doGoToField(a, fieldName, occurrence, row, col, scroll));
|
||||
boolean result = SystemUtilities
|
||||
.runSwingNow(() -> doGoToField(a, fieldName, occurrence, row, col, scroll));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1135,6 +1135,16 @@ public class CodeBrowserPlugin extends Plugin
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListingDisplayListener(ListingDisplayListener listener) {
|
||||
connectedProvider.addListingDisplayListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListingDisplayListener(ListingDisplayListener listener) {
|
||||
connectedProvider.removeListingDisplayListener(listener);
|
||||
}
|
||||
|
||||
public String getCurrentFieldText() {
|
||||
ListingField lf = getCurrentField();
|
||||
if (lf instanceof ListingTextField) {
|
||||
|
||||
+22
-6
@@ -889,8 +889,8 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
||||
int index = saveState.getInt("INDEX", 0);
|
||||
int yOffset = saveState.getInt("Y_OFFSET", 0);
|
||||
ViewerPosition vp = new ViewerPosition(index, 0, yOffset);
|
||||
listingPanel.getFieldPanel().setViewerPosition(vp.getIndex(), vp.getXOffset(),
|
||||
vp.getYOffset());
|
||||
listingPanel.getFieldPanel()
|
||||
.setViewerPosition(vp.getIndex(), vp.getXOffset(), vp.getYOffset());
|
||||
if (program != null) {
|
||||
currentLocation = ProgramLocation.getLocation(program, saveState);
|
||||
if (currentLocation != null) {
|
||||
@@ -906,8 +906,8 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
||||
// (its done in an invoke later)
|
||||
Swing.runLater(() -> {
|
||||
newProvider.doSetProgram(program);
|
||||
newProvider.listingPanel.getFieldPanel().setViewerPosition(vp.getIndex(),
|
||||
vp.getXOffset(), vp.getYOffset());
|
||||
newProvider.listingPanel.getFieldPanel()
|
||||
.setViewerPosition(vp.getIndex(), vp.getXOffset(), vp.getYOffset());
|
||||
newProvider.setLocation(currentLocation);
|
||||
});
|
||||
}
|
||||
@@ -975,8 +975,8 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
||||
public void actionPerformed(ActionContext context) {
|
||||
boolean show = !listingPanel.isHeaderShowing();
|
||||
listingPanel.showHeader(show);
|
||||
getToolBarData().setIcon(
|
||||
show ? LISTING_FORMAT_COLLAPSE_ICON : LISTING_FORMAT_EXPAND_ICON);
|
||||
getToolBarData()
|
||||
.setIcon(show ? LISTING_FORMAT_COLLAPSE_ICON : LISTING_FORMAT_EXPAND_ICON);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1039,4 +1039,20 @@ public class CodeViewerProvider extends NavigatableComponentProviderAdapter
|
||||
return list.toArray(new Highlight[list.size()]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the ListingDisplayListener to the listing panel
|
||||
* @param listener the listener to add
|
||||
*/
|
||||
public void addListingDisplayListener(ListingDisplayListener listener) {
|
||||
listingPanel.addListingDisplayListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the ListingDisplayListener from the listing panel
|
||||
* @param listener the listener to remove
|
||||
*/
|
||||
public void removeListingDisplayListener(ListingDisplayListener listener) {
|
||||
listingPanel.removeListingDisplayListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,12 @@
|
||||
*/
|
||||
package ghidra.app.services;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
|
||||
import docking.action.DockingAction;
|
||||
import docking.widgets.fieldpanel.FieldPanel;
|
||||
import docking.widgets.fieldpanel.Layout;
|
||||
import docking.widgets.fieldpanel.field.Field;
|
||||
import ghidra.app.nav.Navigatable;
|
||||
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
||||
import ghidra.app.util.HighlightProvider;
|
||||
@@ -29,13 +35,6 @@ import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.util.ProgramLocation;
|
||||
import ghidra.program.util.ProgramSelection;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
|
||||
import docking.action.DockingAction;
|
||||
import docking.widgets.fieldpanel.FieldPanel;
|
||||
import docking.widgets.fieldpanel.Layout;
|
||||
import docking.widgets.fieldpanel.field.Field;
|
||||
|
||||
/**
|
||||
* Service provided by a plugin that shows the listing from a Program, i.e., a
|
||||
* Code Viewer. The service allows other plugins to add components and
|
||||
@@ -224,4 +223,16 @@ public interface CodeViewerService {
|
||||
* @return the current program selection.
|
||||
*/
|
||||
public ProgramSelection getCurrentSelection();
|
||||
|
||||
/**
|
||||
* Adds a listener to be notified when the set of visible addresses change.
|
||||
* @param listener the listener to be notified;
|
||||
*/
|
||||
public void addListingDisplayListener(ListingDisplayListener listener);
|
||||
|
||||
/**
|
||||
* Removes listener from being notified when the set of visible addresses change.
|
||||
* @param listener the listener to be notified;
|
||||
*/
|
||||
public void removeListingDisplayListener(ListingDisplayListener listener);
|
||||
}
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.viewer.listingpanel;
|
||||
|
||||
import ghidra.program.model.address.AddressSetView;
|
||||
|
||||
/**
|
||||
* Interface for being notified whenever the set of visible addresses change in the listing.
|
||||
*/
|
||||
public interface ListingDisplayListener {
|
||||
/**
|
||||
* Callback whenever the set of visible addresses change in the listing.
|
||||
* @param visibleAddresses the current set of visible addresses in the listing. If no
|
||||
* visible addresses are in the listing view, then an empty AddressSetView will be passed.
|
||||
*/
|
||||
void visibleAddressesChanged(AddressSetView visibleAddresses);
|
||||
}
|
||||
+26
-2
@@ -45,6 +45,7 @@ import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.program.util.*;
|
||||
import ghidra.util.Msg;
|
||||
import ghidra.util.layout.HorizontalLayout;
|
||||
|
||||
public class ListingPanel extends JPanel implements FieldMouseListener, FieldLocationListener,
|
||||
@@ -88,6 +89,7 @@ public class ListingPanel extends JPanel implements FieldMouseListener, FieldLoc
|
||||
// don't care
|
||||
}
|
||||
};
|
||||
private List<ListingDisplayListener> displayListeners = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Constructs a new ListingPanel using the given FormatManager and ServiceProvider.
|
||||
@@ -461,6 +463,21 @@ public class ListingPanel extends JPanel implements FieldMouseListener, FieldLoc
|
||||
for (MarginProvider element : marginProviders) {
|
||||
element.setPixelMap(pixmap);
|
||||
}
|
||||
|
||||
for (ListingDisplayListener listener : displayListeners) {
|
||||
notifyDisplayListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyDisplayListener(ListingDisplayListener listener) {
|
||||
AddressSetView displayAddresses = pixmap.getAddressSet();
|
||||
try {
|
||||
listener.visibleAddressesChanged(displayAddresses);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
Msg.showError(this, fieldPanel, "Error in Display Listener",
|
||||
"Execption encountered when notifying listeners of change in display", t);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -843,8 +860,8 @@ public class ListingPanel extends JPanel implements FieldMouseListener, FieldLoc
|
||||
FieldLocation dropLoc = new FieldLocation();
|
||||
ListingField field = (ListingField) fieldPanel.getFieldAt(point.x, point.y, dropLoc);
|
||||
if (field != null) {
|
||||
return field.getFieldFactory().getProgramLocation(dropLoc.getRow(), dropLoc.getCol(),
|
||||
field);
|
||||
return field.getFieldFactory()
|
||||
.getProgramLocation(dropLoc.getRow(), dropLoc.getCol(), field);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -1091,4 +1108,11 @@ public class ListingPanel extends JPanel implements FieldMouseListener, FieldLoc
|
||||
layoutModel.dataChanged(true);
|
||||
}
|
||||
|
||||
public void addListingDisplayListener(ListingDisplayListener listener) {
|
||||
displayListeners.add(listener);
|
||||
}
|
||||
|
||||
public void removeListingDisplayListener(ListingDisplayListener listener) {
|
||||
displayListeners.remove(listener);
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -128,6 +128,10 @@ public class VerticalPixelAddressMapImpl implements VerticalPixelAddressMap {
|
||||
|
||||
@Override
|
||||
public AddressSetView getAddressSet() {
|
||||
// If there are no visible layouts (no open data to display or listing component height = 0)
|
||||
if (layouts.isEmpty()) {
|
||||
return new AddressSet();
|
||||
}
|
||||
if (viewedAddresses == null) {
|
||||
viewedAddresses =
|
||||
map.getOriginalAddressSet().intersectRange(getStartAddress(), getEndAddress());
|
||||
|
||||
+27
-4
@@ -18,6 +18,7 @@ package ghidra.app.util.viewer.listingpanel;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
@@ -51,10 +52,6 @@ public class ListingPanelTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
private AddressFactory addrFactory;
|
||||
private AddressSpace space;
|
||||
|
||||
public ListingPanelTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
env = new TestEnv();
|
||||
@@ -305,6 +302,32 @@ public class ListingPanelTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListingDisplayListener() {
|
||||
showTool(tool);
|
||||
|
||||
AtomicReference<AddressSetView> addresses = new AtomicReference<>();
|
||||
CodeViewerService cvs = tool.getService(CodeViewerService.class);
|
||||
cvs.addListingDisplayListener(new ListingDisplayListener() {
|
||||
@Override
|
||||
public void visibleAddressesChanged(AddressSetView visibleAddresses) {
|
||||
addresses.set(visibleAddresses);
|
||||
}
|
||||
});
|
||||
|
||||
assertNull(addresses.get());
|
||||
cvs.goTo(new ProgramLocation(program, addr(0x1008000)), false);
|
||||
assertNotNull(addresses.get());
|
||||
assertTrue(addresses.get().contains(addr(0x1008000)));
|
||||
assertFalse(addresses.get().contains(addr(0x1001000)));
|
||||
|
||||
cvs.goTo(new ProgramLocation(program, addr(0x1001000)), false);
|
||||
assertNotNull(addresses.get());
|
||||
assertFalse(addresses.get().contains(addr(0x1008000)));
|
||||
assertTrue(addresses.get().contains(addr(0x1001000)));
|
||||
|
||||
}
|
||||
|
||||
private void resetFormatOptions() {
|
||||
Options fieldOptions = cb.getFormatManager().getFieldOptions();
|
||||
List<String> names = fieldOptions.getOptionNames();
|
||||
|
||||
Reference in New Issue
Block a user