mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-02-18 00:20:10 +00:00
GP-1318 - fixed xref clicking bug
This commit is contained in:
parent
f00f7afa6b
commit
f24e969c2a
@ -25,11 +25,13 @@ import javax.swing.table.TableModel;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.action.DockingActionIf;
|
||||
import docking.widgets.OptionDialog;
|
||||
import docking.widgets.combobox.GhidraComboBox;
|
||||
import docking.widgets.dialogs.InputWithChoicesDialog;
|
||||
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
||||
import ghidra.app.plugin.core.codebrowser.CodeViewerProvider;
|
||||
import ghidra.app.services.ProgramManager;
|
||||
import ghidra.framework.Application;
|
||||
import ghidra.framework.options.Options;
|
||||
@ -307,8 +309,12 @@ public class AnalysisOptionsTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
}
|
||||
|
||||
private AnalysisOptionsDialog invokeAnalysisDialog() {
|
||||
|
||||
CodeBrowserPlugin cbp = env.getPlugin(CodeBrowserPlugin.class);
|
||||
CodeViewerProvider provider = cbp.getProvider();
|
||||
DockingActionIf action = getAction(tool, "Auto Analyze");
|
||||
performAction(action, false);
|
||||
ActionContext context = runSwing(() -> provider.getActionContext(null));
|
||||
performAction(action, context, false);
|
||||
|
||||
// TODO temp debug to catch issue seen when running parallel tests
|
||||
try {
|
||||
@ -331,24 +337,14 @@ public class AnalysisOptionsTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
private void setAnalyzerEnabled(String name, boolean enabled) {
|
||||
TableModel model = getAnalyzerTableModel();
|
||||
int analyzerRow = getRowForAnalyzer(name, model);
|
||||
runSwing(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
model.setValueAt(enabled, analyzerRow, 0);
|
||||
}
|
||||
});
|
||||
runSwing(() -> model.setValueAt(enabled, analyzerRow, 0));
|
||||
}
|
||||
|
||||
private boolean isAnalyzerEnabled(String name) {
|
||||
TableModel model = getAnalyzerTableModel();
|
||||
int analyzerRow = getRowForAnalyzer(name, model);
|
||||
AtomicBoolean result = new AtomicBoolean();
|
||||
runSwing(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
result.set((Boolean) model.getValueAt(analyzerRow, 0));
|
||||
}
|
||||
});
|
||||
runSwing(() -> result.set((Boolean) model.getValueAt(analyzerRow, 0)));
|
||||
return result.get();
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,8 @@ public class CompositeVerticalLayoutTextField implements TextField {
|
||||
private List<FieldRow> layoutRows(List<TextField> fields, int maxLines) {
|
||||
|
||||
List<FieldRow> newSubFields = new ArrayList<>();
|
||||
int heightSoFar = -heightAbove;
|
||||
int startY = -heightAbove;
|
||||
int ySoFar = startY;
|
||||
int currentRow = 0;
|
||||
boolean tooManyLines = fields.size() > maxLines;
|
||||
for (int i = 0; i < fields.size() && i < maxLines; i++) {
|
||||
@ -124,15 +125,15 @@ public class CompositeVerticalLayoutTextField implements TextField {
|
||||
if (tooManyLines && (i == maxLines - 1)) {
|
||||
FieldElement element = field.getFieldElement(0, 0);
|
||||
TextField newField = createClippedField(element);
|
||||
newSubFields.add(new FieldRow(newField, currentRow, heightSoFar));
|
||||
newSubFields.add(new FieldRow(newField, currentRow, ySoFar));
|
||||
isClipped = true;
|
||||
}
|
||||
else {
|
||||
newSubFields.add(new FieldRow(field, currentRow, heightSoFar));
|
||||
newSubFields.add(new FieldRow(field, currentRow, ySoFar));
|
||||
isClipped |= field.isClipped();
|
||||
}
|
||||
|
||||
heightSoFar += field.getHeight();
|
||||
ySoFar += field.getHeight();
|
||||
currentRow += field.getNumRows();
|
||||
}
|
||||
|
||||
@ -402,31 +403,42 @@ public class CompositeVerticalLayoutTextField implements TextField {
|
||||
@Override
|
||||
public int getY(int row) {
|
||||
|
||||
int y = -heightAbove;
|
||||
int startY = -heightAbove;
|
||||
int ySoFar = startY;
|
||||
List<FieldRow> rows = getAllRows(row);
|
||||
int lastHeight = 0;
|
||||
for (FieldRow fieldRow : rows) {
|
||||
y += fieldRow.field.getHeight();
|
||||
ySoFar += lastHeight;
|
||||
if (fieldRow.displayRowOffset >= row) {
|
||||
return ySoFar;
|
||||
}
|
||||
lastHeight = fieldRow.field.getHeight();
|
||||
}
|
||||
return y;
|
||||
|
||||
return ySoFar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRow(int y) {
|
||||
if (y < 0) {
|
||||
|
||||
// our start y value is our baseline - the heigh above the baseline
|
||||
int startY = -heightAbove;
|
||||
if (y < startY) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int heightSoFar = 0;
|
||||
int ySoFar = startY;
|
||||
|
||||
for (FieldRow fieldRow : fieldRows) {
|
||||
int fieldHeight = fieldRow.field.getHeight();
|
||||
int bottom = fieldHeight + heightSoFar;
|
||||
int bottom = fieldHeight + ySoFar;
|
||||
if (bottom > y) {
|
||||
int relativeY = y - heightSoFar;
|
||||
int relativeY = y - ySoFar;
|
||||
int relativeRow = fieldRow.field.getRow(relativeY);
|
||||
int displayRow = fieldRow.fromRelativeRow(relativeRow);
|
||||
return displayRow;
|
||||
}
|
||||
heightSoFar += fieldHeight;
|
||||
ySoFar += fieldHeight;
|
||||
}
|
||||
return getNumRows() - 1;
|
||||
}
|
||||
|
@ -208,20 +208,23 @@ public class VerticalLayoutTextField implements TextField {
|
||||
|
||||
@Override
|
||||
public int getRow(int y) {
|
||||
if (y < -heightAbove) {
|
||||
|
||||
// our start y value is our baseline - the heigh above the baseline
|
||||
int startY = -heightAbove;
|
||||
if (y < startY) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int heightSoFar = -heightAbove;
|
||||
|
||||
int ySoFar = startY;
|
||||
int n = subFields.size();
|
||||
for (int i = 0; i < n; i++) {
|
||||
Field f = getField(i);
|
||||
heightSoFar += f.getHeight();
|
||||
if (heightSoFar > y) {
|
||||
ySoFar += f.getHeight();
|
||||
if (ySoFar > y) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return n - 1;
|
||||
}
|
||||
|
||||
@ -234,11 +237,14 @@ public class VerticalLayoutTextField implements TextField {
|
||||
@Override
|
||||
public int getY(int row) {
|
||||
|
||||
int y = -heightAbove;
|
||||
for (int i = 0; i < row; i++) {
|
||||
int startY = -heightAbove;
|
||||
int y = startY;
|
||||
int n = Math.min(row, subFields.size() - 1);
|
||||
for (int i = 0; i < n; i++) {
|
||||
Field f = getField(i);
|
||||
y += f.getHeight();
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
@ -537,6 +543,9 @@ public class VerticalLayoutTextField implements TextField {
|
||||
}
|
||||
|
||||
private TextField getField(int screenRow) {
|
||||
if (screenRow >= subFields.size()) {
|
||||
return null;
|
||||
}
|
||||
return subFields.get(screenRow).field;
|
||||
}
|
||||
|
||||
|
@ -93,6 +93,7 @@ public class RowLayout implements Layout {
|
||||
|
||||
/**
|
||||
* Returns the height above the baseline.
|
||||
* @return the height above the baseline.
|
||||
*/
|
||||
public int getHeightAbove() {
|
||||
return heightAbove;
|
||||
@ -100,6 +101,7 @@ public class RowLayout implements Layout {
|
||||
|
||||
/**
|
||||
* Returns the height below the baseline.
|
||||
* @return the height below the baseline.
|
||||
*/
|
||||
public int getHeightBelow() {
|
||||
return heightBelow;
|
||||
@ -107,6 +109,7 @@ public class RowLayout implements Layout {
|
||||
|
||||
/**
|
||||
* Returns the row number of this layout with respect to its containing layout.
|
||||
* @return the row number of this layout with respect to its containing layout.
|
||||
*/
|
||||
public int getRowID() {
|
||||
return rowID;
|
||||
@ -201,8 +204,12 @@ public class RowLayout implements Layout {
|
||||
|
||||
Field field = fields[index];
|
||||
|
||||
// y passed-in is 0-based; update y to be relative to our starting position, which is
|
||||
// the tallest field in this group of fields, using that field's height above its font
|
||||
// baseline.
|
||||
int offsetY = y - heightAbove;
|
||||
cursorLoc.fieldNum = index;
|
||||
cursorLoc.row = field.getRow(y);
|
||||
cursorLoc.row = field.getRow(offsetY);
|
||||
cursorLoc.col = field.getCol(cursorLoc.row, x);
|
||||
return field.getX(cursorLoc.row, cursorLoc.col);
|
||||
}
|
||||
@ -374,6 +381,9 @@ public class RowLayout implements Layout {
|
||||
* Finds the most appropriate field to place the cursor for the given horizontal
|
||||
* position. If the position is between fields, first try to the left and if that
|
||||
* doesn't work, try to the right.
|
||||
* @param x the x value
|
||||
* @param y the y value
|
||||
* @return the index
|
||||
*/
|
||||
int findAppropriateFieldIndex(int x, int y) {
|
||||
y -= heightAbove;
|
||||
@ -399,33 +409,6 @@ public class RowLayout implements Layout {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the selection background for individual fields.
|
||||
*/
|
||||
// private void drawSelection(Graphics g,int startField, int endField) {
|
||||
// int start = fields[startField].getStartX();
|
||||
// int end = fields[endField].getStartX()+fields[endField].getWidth();
|
||||
// int width = end-start;
|
||||
// g.fillRect(start,0,width,heightAbove+heightBelow);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Draws the selection background for individual fields.
|
||||
*/
|
||||
// private void drawSelection(Graphics g, int startField, int endField,
|
||||
// int first, int last) {
|
||||
// int start = fields[startField].getStartX();
|
||||
// int end = fields[endField].getStartX()+fields[endField].getWidth();
|
||||
// if (first != -1 && first < start) {
|
||||
// start = first;
|
||||
// }
|
||||
// if (last != -1 && last > end) {
|
||||
// end = last;
|
||||
// }
|
||||
// int width = end-start;
|
||||
// g.fillRect(start,0,width,heightAbove+heightBelow);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public int getPrimaryOffset() {
|
||||
return 0;
|
||||
|
@ -32,13 +32,13 @@ public class VerticalLayoutTextFieldTest extends AbstractGenericTest {
|
||||
|
||||
private static final String CLIPPED_STRING = "Supercalifragilisticexpialidocious";
|
||||
|
||||
private VerticalLayoutTextField textField;
|
||||
private VerticalLayoutTextField field;
|
||||
|
||||
@SuppressWarnings("deprecation") // we mean to use getFontMetrics
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
HighlightFactory factory = (field, text, cursorTextOffset) -> {
|
||||
HighlightFactory factory = (f, text, cursorTextOffset) -> {
|
||||
return new Highlight[] { new Highlight(4, 4, Color.YELLOW) };
|
||||
};
|
||||
|
||||
@ -55,61 +55,94 @@ public class VerticalLayoutTextFieldTest extends AbstractGenericTest {
|
||||
new TextFieldElement(new AttributedString(CLIPPED_STRING, Color.GREEN, fm), 2, 0));
|
||||
elements.add(new TextFieldElement(new AttributedString("Wow!", Color.GRAY, fm), 3, 0));
|
||||
|
||||
textField = new VerticalLayoutTextField(elements, 100, 100, 5, factory);
|
||||
field = new VerticalLayoutTextField(elements, 100, 100, 5, factory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScreenToDataLocation() {
|
||||
assertEquals(new RowColLocation(0, 0), textField.screenToDataLocation(0, 0));
|
||||
assertEquals(new RowColLocation(0, 2), textField.screenToDataLocation(0, 2));
|
||||
assertEquals(new RowColLocation(0, 5), textField.screenToDataLocation(0, 5));
|
||||
assertEquals(new RowColLocation(0, 5), textField.screenToDataLocation(0, 6));
|
||||
assertEquals(new RowColLocation(0, 5), textField.screenToDataLocation(0, 75));
|
||||
assertEquals(new RowColLocation(0, 0), field.screenToDataLocation(0, 0));
|
||||
assertEquals(new RowColLocation(0, 2), field.screenToDataLocation(0, 2));
|
||||
assertEquals(new RowColLocation(0, 5), field.screenToDataLocation(0, 5));
|
||||
assertEquals(new RowColLocation(0, 5), field.screenToDataLocation(0, 6));
|
||||
assertEquals(new RowColLocation(0, 5), field.screenToDataLocation(0, 75));
|
||||
|
||||
assertEquals(new RowColLocation(1, 0), textField.screenToDataLocation(1, 0));
|
||||
assertEquals(new RowColLocation(1, 5), textField.screenToDataLocation(1, 6));
|
||||
assertEquals(new RowColLocation(1, 5), textField.screenToDataLocation(1, 16));
|
||||
assertEquals(new RowColLocation(1, 0), field.screenToDataLocation(1, 0));
|
||||
assertEquals(new RowColLocation(1, 5), field.screenToDataLocation(1, 6));
|
||||
assertEquals(new RowColLocation(1, 5), field.screenToDataLocation(1, 16));
|
||||
|
||||
assertEquals(new RowColLocation(2, 0), textField.screenToDataLocation(2, 0));
|
||||
assertEquals(new RowColLocation(2, 4), textField.screenToDataLocation(2, 4));
|
||||
assertEquals(new RowColLocation(2, 34), textField.screenToDataLocation(2, 75));
|
||||
assertEquals(new RowColLocation(2, 0), field.screenToDataLocation(2, 0));
|
||||
assertEquals(new RowColLocation(2, 4), field.screenToDataLocation(2, 4));
|
||||
assertEquals(new RowColLocation(2, 34), field.screenToDataLocation(2, 75));
|
||||
|
||||
assertEquals(new RowColLocation(3, 0), textField.screenToDataLocation(3, 0));
|
||||
assertEquals(new RowColLocation(3, 4), textField.screenToDataLocation(50, 75));
|
||||
assertEquals(new RowColLocation(3, 0), field.screenToDataLocation(3, 0));
|
||||
assertEquals(new RowColLocation(3, 4), field.screenToDataLocation(50, 75));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataToScreenLocation() {
|
||||
assertEquals(new RowColLocation(0, 0), textField.dataToScreenLocation(0, 0));
|
||||
assertEquals(new RowColLocation(0, 2), textField.dataToScreenLocation(0, 2));
|
||||
assertEquals(new RowColLocation(0, 5), textField.dataToScreenLocation(0, 5));
|
||||
assertEquals(new RowColLocation(0, 0), field.dataToScreenLocation(0, 0));
|
||||
assertEquals(new RowColLocation(0, 2), field.dataToScreenLocation(0, 2));
|
||||
assertEquals(new RowColLocation(0, 5), field.dataToScreenLocation(0, 5));
|
||||
|
||||
assertEquals(new RowColLocation(1, 0), textField.dataToScreenLocation(1, 0));
|
||||
assertEquals(new RowColLocation(1, 4), textField.dataToScreenLocation(1, 4));
|
||||
assertEquals(new RowColLocation(1, 5), textField.dataToScreenLocation(1, 5));
|
||||
assertEquals(new RowColLocation(1, 0), field.dataToScreenLocation(1, 0));
|
||||
assertEquals(new RowColLocation(1, 4), field.dataToScreenLocation(1, 4));
|
||||
assertEquals(new RowColLocation(1, 5), field.dataToScreenLocation(1, 5));
|
||||
|
||||
assertEquals(new RowColLocation(2, 0), textField.dataToScreenLocation(2, 0));
|
||||
assertEquals(new RowColLocation(2, 4), textField.dataToScreenLocation(2, 4));
|
||||
assertEquals(new RowColLocation(2, 12), textField.dataToScreenLocation(2, 12));
|
||||
assertEquals(new DefaultRowColLocation(2, 12), textField.dataToScreenLocation(2, 15));
|
||||
assertEquals(new RowColLocation(2, 0), field.dataToScreenLocation(2, 0));
|
||||
assertEquals(new RowColLocation(2, 4), field.dataToScreenLocation(2, 4));
|
||||
assertEquals(new RowColLocation(2, 12), field.dataToScreenLocation(2, 12));
|
||||
assertEquals(new DefaultRowColLocation(2, 12), field.dataToScreenLocation(2, 15));
|
||||
|
||||
assertEquals(new RowColLocation(3, 0), textField.dataToScreenLocation(3, 0));
|
||||
assertEquals(new RowColLocation(3, 4), textField.dataToScreenLocation(3, 4));
|
||||
assertEquals(new RowColLocation(3, 0), field.dataToScreenLocation(3, 0));
|
||||
assertEquals(new RowColLocation(3, 4), field.dataToScreenLocation(3, 4));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTextOffsetToScreenLocation() {
|
||||
assertEquals(new RowColLocation(0, 0), textField.textOffsetToScreenLocation(0));
|
||||
assertEquals(new RowColLocation(0, 5), textField.textOffsetToScreenLocation(5));
|
||||
assertEquals(new RowColLocation(0, 0), field.textOffsetToScreenLocation(0));
|
||||
assertEquals(new RowColLocation(0, 5), field.textOffsetToScreenLocation(5));
|
||||
|
||||
assertEquals(new RowColLocation(1, 0), textField.textOffsetToScreenLocation(6));
|
||||
assertEquals(new RowColLocation(1, 4), textField.textOffsetToScreenLocation(10));
|
||||
assertEquals(new RowColLocation(1, 5), textField.textOffsetToScreenLocation(11));
|
||||
assertEquals(new RowColLocation(1, 0), field.textOffsetToScreenLocation(6));
|
||||
assertEquals(new RowColLocation(1, 4), field.textOffsetToScreenLocation(10));
|
||||
assertEquals(new RowColLocation(1, 5), field.textOffsetToScreenLocation(11));
|
||||
|
||||
assertEquals(new RowColLocation(2, 0), textField.textOffsetToScreenLocation(12));
|
||||
assertEquals(new RowColLocation(2, 0), field.textOffsetToScreenLocation(12));
|
||||
|
||||
assertEquals(new RowColLocation(1, 4), textField.textOffsetToScreenLocation(10));
|
||||
assertEquals(new RowColLocation(1, 4), field.textOffsetToScreenLocation(10));
|
||||
|
||||
assertEquals(new DefaultRowColLocation(3, 4), textField.textOffsetToScreenLocation(1000));
|
||||
assertEquals(new DefaultRowColLocation(3, 4), field.textOffsetToScreenLocation(1000));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetY_And_GetRow() {
|
||||
|
||||
int y = field.getY(0);
|
||||
int row = field.getRow(y);
|
||||
assertEquals("Wrong row for y value: " + y, 0, row);
|
||||
|
||||
y = field.getY(1);
|
||||
row = field.getRow(y);
|
||||
assertEquals("Wrong row for y value: " + y, 1, row);
|
||||
|
||||
y = field.getY(2);
|
||||
row = field.getRow(y);
|
||||
assertEquals("Wrong row for y value: " + y, 2, row);
|
||||
|
||||
y = field.getY(3);
|
||||
row = field.getRow(y);
|
||||
assertEquals("Wrong row for y value: " + y, 3, row);
|
||||
|
||||
// try values past the end
|
||||
int yForRowTooBig = field.getY(10);
|
||||
assertEquals(y, yForRowTooBig);
|
||||
int rowForYTooBig = field.getRow(1000);
|
||||
assertEquals(3, rowForYTooBig);
|
||||
|
||||
// try values before the beginning
|
||||
int yForRowTooSmall = field.getY(-1);
|
||||
int expectedY = -field.getHeightAbove();
|
||||
assertEquals(expectedY, yForRowTooSmall);
|
||||
int rowForYTooSmall = field.getRow(-1000);
|
||||
assertEquals(0, rowForYTooSmall);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user