mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-24 05:02:41 +00:00
Merge remote-tracking branch 'origin/GP-0-dragonmacher-test-fixes-11-19-24'
This commit is contained in:
commit
79b008d7e4
@ -207,8 +207,7 @@ public class StructureEditorUnlockedCellEdit2Test extends AbstractStructureEdito
|
||||
assertEquals(model.getDataTypeColumn(), model.getColumn());
|
||||
|
||||
// Bad value allows escape.
|
||||
escape();
|
||||
escape();
|
||||
escape(); // cancel editing
|
||||
waitForSwing();
|
||||
assertTrue(!model.isEditingField());
|
||||
assertEquals(1, model.getNumSelectedRows());
|
||||
|
@ -19,7 +19,6 @@ import static org.junit.Assert.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.JTextField;
|
||||
@ -27,8 +26,6 @@ import javax.swing.table.TableModel;
|
||||
|
||||
import org.junit.*;
|
||||
|
||||
import docking.ActionContext;
|
||||
import docking.DefaultActionContext;
|
||||
import docking.action.DockingActionIf;
|
||||
import ghidra.app.cmd.memory.*;
|
||||
import ghidra.app.plugin.core.codebrowser.CodeBrowserPlugin;
|
||||
@ -93,58 +90,6 @@ public class MemoryMapPluginTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
assertTrue(action.isEnabled());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpenProgram() throws Exception {
|
||||
env.close(program);
|
||||
program = buildProgram("sdk");
|
||||
env.open(program);
|
||||
Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
|
||||
for (DockingActionIf action : actions) {
|
||||
String name = action.getName();
|
||||
if (name.equals("Add Block") || name.equals("Set Image Base") ||
|
||||
name.equals("Memory Map") || name.equals("Close Window") ||
|
||||
name.contains("Table")) {
|
||||
assertActionEnabled(action, getActionContext(), true);
|
||||
}
|
||||
else {
|
||||
assertActionEnabled(action, getActionContext(), false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCloseProgram() {
|
||||
env.close(program);
|
||||
JTable table = provider.getTable();
|
||||
assertEquals(0, table.getModel().getRowCount());
|
||||
Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
|
||||
for (DockingActionIf action : actions) {
|
||||
String name = action.getName();
|
||||
if (name.equals("Memory Map") || name.equals("Close Window") ||
|
||||
name.equals("Local Menu")) {
|
||||
continue;
|
||||
}
|
||||
assertActionEnabled(action, getActionContext(), false);
|
||||
}
|
||||
}
|
||||
|
||||
private void assertActionEnabled(DockingActionIf action, ActionContext context,
|
||||
boolean shouldBeEnabled) {
|
||||
|
||||
String text = shouldBeEnabled ? "should be enabled" : "should be disabled";
|
||||
assertEquals("Action " + text + ", but is not: '" + action.getFullName() + "'",
|
||||
shouldBeEnabled, action.isEnabledForContext(context));
|
||||
}
|
||||
|
||||
private ActionContext getActionContext() {
|
||||
ActionContext context = provider.getActionContext(null);
|
||||
if (context == null) {
|
||||
return new DefaultActionContext();
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBlockNameChanged() throws Exception {
|
||||
MemoryBlock block = memory.getBlock(program.getMinAddress());
|
||||
|
@ -124,29 +124,6 @@ public class MemoryMapProvider1Test extends AbstractGhidraHeadedIntegrationTest
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiSelection() {
|
||||
|
||||
table.addRowSelectionInterval(0, 1);
|
||||
assertEquals(2, table.getSelectedRowCount());
|
||||
Set<DockingActionIf> actions = getActionsByOwner(tool, plugin.getName());
|
||||
for (DockingActionIf action : actions) {
|
||||
String name = action.getName();
|
||||
if (name.equals("Add Block") || name.equals("Merge Blocks") ||
|
||||
name.equals("Delete Block") || name.equals("Set Image Base") ||
|
||||
name.equals("Memory Map") || name.equals("Close Window") ||
|
||||
name.equals("Make Selection")) {
|
||||
assertTrue("Action should be enabled for a multi-row selection - '" + name + "'",
|
||||
action.isEnabled());
|
||||
}
|
||||
else {
|
||||
assertFalse(
|
||||
"Action should not be enabled for a multi-row selection - '" + name + "'",
|
||||
action.isEnabled());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGoToAddress() {
|
||||
Rectangle rect = table.getCellRect(2, MemoryMapModel.START, true);
|
||||
|
@ -177,79 +177,6 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
|
||||
return previewLabel;
|
||||
}
|
||||
|
||||
// overridden to grab the Escape and enter key events before our parent window gets them
|
||||
@Override
|
||||
protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) {
|
||||
|
||||
if (handleEscapeKey(ks, e, condition, pressed)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (handleEnterKey(ks, e, condition, pressed)) {
|
||||
return true;
|
||||
}
|
||||
return super.processKeyBinding(ks, e, condition, pressed);
|
||||
}
|
||||
|
||||
private boolean handleEscapeKey(KeyStroke ks, KeyEvent e, int condition, boolean pressed) {
|
||||
if ((condition == JComponent.WHEN_FOCUSED) && (ks.getKeyCode() == KeyEvent.VK_ESCAPE)) {
|
||||
|
||||
if (getMatchingWindow().isShowing()) {
|
||||
hideMatchingWindow();
|
||||
e.consume();
|
||||
return true;
|
||||
}
|
||||
else if (pressed) {
|
||||
// do not return after this call so that the event will continue to be processed
|
||||
fireEditingCancelled();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean handleEnterKey(KeyStroke ks, KeyEvent e, int condition, boolean pressed) {
|
||||
if ((condition != JComponent.WHEN_FOCUSED) || (ks.getKeyCode() != KeyEvent.VK_ENTER)) {
|
||||
return false; // enter key not pressed!
|
||||
}
|
||||
|
||||
if (ignoreEnterKeyPress) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// O.K., if we are consuming key presses, then we only want to do so when the selection
|
||||
// window is showing. This will close the selection window and not send the Enter event up
|
||||
// to our parent component.
|
||||
boolean listShowing = isMatchingListShowing();
|
||||
if (consumeEnterKeyPress) {
|
||||
if (listShowing) {
|
||||
setTextFromListOnEnterPress();
|
||||
validateChosenItemAgainstText(true);
|
||||
e.consume();
|
||||
return true; // don't let our parent see the event
|
||||
}
|
||||
else if (pressed) {
|
||||
validateChosenItemAgainstText(false);
|
||||
fireEditingStopped();
|
||||
}
|
||||
|
||||
// Return false, even though 'consumeEnterKeyPress' is set, so that our
|
||||
// parent can process the event.
|
||||
return false;
|
||||
}
|
||||
|
||||
// When we aren't consuming Enter key presses, then we just take the user's selection
|
||||
// and signal that editing is finished, while letting our parent component handle the event
|
||||
if (pressed) {
|
||||
setTextFromListOnEnterPress();
|
||||
validateChosenItemAgainstText(listShowing);
|
||||
fireEditingStopped();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void validateChosenItemAgainstText(boolean isListShowing) {
|
||||
//
|
||||
// If the text differs from that of the chosen item, then the implication is the user has
|
||||
@ -884,62 +811,117 @@ public class DropDownTextField<T> extends JTextField implements GComponent {
|
||||
KeyEvent.VK_KP_DOWN)) {
|
||||
//@formatter:on
|
||||
|
||||
if (!getMatchingWindow().isShowing()) {
|
||||
updateDisplayContents(getText());
|
||||
event.consume();
|
||||
}
|
||||
else { // update the window if it is showing
|
||||
if (keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_KP_UP) {
|
||||
decrementListSelection();
|
||||
}
|
||||
else {
|
||||
incrementListSelection();
|
||||
}
|
||||
event.consume();
|
||||
setTextFromSelectedListItemAndKeepMatchingWindowOpen();
|
||||
}
|
||||
handleArrowKey(event);
|
||||
}
|
||||
else if (keyCode == KeyEvent.VK_ENTER) {
|
||||
handleEnterKey(event);
|
||||
}
|
||||
else if (keyCode == KeyEvent.VK_ESCAPE) {
|
||||
handleEscapeKey(event);
|
||||
}
|
||||
|
||||
setToolTipText(getToolTipText());
|
||||
}
|
||||
|
||||
private void incrementListSelection() {
|
||||
int index = list.getSelectedIndex();
|
||||
int listSize = list.getModel().getSize();
|
||||
|
||||
if (index < 0) { // no selection
|
||||
index = 0;
|
||||
private void handleEscapeKey(KeyEvent event) {
|
||||
if (getMatchingWindow().isShowing()) {
|
||||
hideMatchingWindow();
|
||||
}
|
||||
else if (index == listSize - 1) { // last element selected - wrap
|
||||
index = 0;
|
||||
else {
|
||||
fireEditingCancelled();
|
||||
}
|
||||
else { // just increment
|
||||
index++;
|
||||
}
|
||||
|
||||
list.setSelectedIndex(index);
|
||||
list.ensureIndexIsVisible(index);
|
||||
event.consume();
|
||||
}
|
||||
|
||||
private void decrementListSelection() {
|
||||
int index = list.getSelectedIndex();
|
||||
int listSize = list.getModel().getSize();
|
||||
private void handleEnterKey(KeyEvent event) {
|
||||
|
||||
if (index < 0) { // no selection
|
||||
index = 0;
|
||||
}
|
||||
else if (index == 0) { // first element - wrap
|
||||
index = listSize - 1;
|
||||
}
|
||||
else { // just decrement
|
||||
index--;
|
||||
if (ignoreEnterKeyPress) {
|
||||
return;
|
||||
}
|
||||
|
||||
list.setSelectedIndex(index);
|
||||
list.ensureIndexIsVisible(index);
|
||||
// O.K., if we are consuming key presses, then we only want to do so when the selection
|
||||
// window is showing. This will close the selection window and not send the Enter event up
|
||||
// to our parent component.
|
||||
boolean listShowing = isMatchingListShowing();
|
||||
if (consumeEnterKeyPress) {
|
||||
if (listShowing) {
|
||||
setTextFromListOnEnterPress();
|
||||
validateChosenItemAgainstText(true);
|
||||
event.consume();
|
||||
return; // don't let our parent see the event
|
||||
}
|
||||
|
||||
validateChosenItemAgainstText(false);
|
||||
fireEditingStopped();
|
||||
|
||||
// Even though 'consumeEnterKeyPress' is set, do not consume the event so that our
|
||||
// parent can process the event.
|
||||
return;
|
||||
}
|
||||
|
||||
// When we aren't consuming Enter key presses, then just take the user's selection and
|
||||
// signal that editing is finished, while letting our parent component handle the event
|
||||
setTextFromListOnEnterPress();
|
||||
validateChosenItemAgainstText(listShowing);
|
||||
fireEditingStopped();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleArrowKey(KeyEvent event) {
|
||||
|
||||
int keyCode = event.getKeyCode();
|
||||
if (!getMatchingWindow().isShowing()) {
|
||||
updateDisplayContents(getText());
|
||||
event.consume();
|
||||
}
|
||||
else { // update the window if it is showing
|
||||
if (keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_KP_UP) {
|
||||
decrementListSelection();
|
||||
}
|
||||
else {
|
||||
incrementListSelection();
|
||||
}
|
||||
event.consume();
|
||||
setTextFromSelectedListItemAndKeepMatchingWindowOpen();
|
||||
}
|
||||
}
|
||||
|
||||
private void incrementListSelection() {
|
||||
int index = list.getSelectedIndex();
|
||||
int listSize = list.getModel().getSize();
|
||||
|
||||
if (index < 0) { // no selection
|
||||
index = 0;
|
||||
}
|
||||
else if (index == listSize - 1) { // last element selected - wrap
|
||||
index = 0;
|
||||
}
|
||||
else { // just increment
|
||||
index++;
|
||||
}
|
||||
|
||||
list.setSelectedIndex(index);
|
||||
list.ensureIndexIsVisible(index);
|
||||
}
|
||||
|
||||
private void decrementListSelection() {
|
||||
int index = list.getSelectedIndex();
|
||||
int listSize = list.getModel().getSize();
|
||||
|
||||
if (index < 0) { // no selection
|
||||
index = 0;
|
||||
}
|
||||
else if (index == 0) { // first element - wrap
|
||||
index = listSize - 1;
|
||||
}
|
||||
else { // just decrement
|
||||
index--;
|
||||
}
|
||||
|
||||
list.setSelectedIndex(index);
|
||||
list.ensureIndexIsVisible(index);
|
||||
}
|
||||
|
||||
// we know the cast is safe because we put the items in the list
|
||||
protected void setTextFromSelectedListItemAndKeepMatchingWindowOpen() {
|
||||
T selectedItem = list.getSelectedValue();
|
||||
|
@ -245,10 +245,12 @@ public abstract class AbstractSortedTableModel<T> extends AbstractGTableModel<T>
|
||||
protected TableSortingContext<T> createSortingContext(TableSortState newSortState) {
|
||||
|
||||
if (!isValidSortState(newSortState)) {
|
||||
Msg.error(this, """
|
||||
"Table '%s' sort is invalid. Assuming columns have been removed. \
|
||||
Setting unsorted.""".formatted(getName()));
|
||||
newSortState = TableSortState.createUnsortedSortState();
|
||||
if (!isDisposed) {
|
||||
Msg.error(this, """
|
||||
"Table '%s' sort is invalid. Assuming columns have been removed. \
|
||||
Setting unsorted.""".formatted(getName()));
|
||||
}
|
||||
}
|
||||
|
||||
return new TableSortingContext<>(newSortState, getComparatorChain(newSortState));
|
||||
|
Loading…
Reference in New Issue
Block a user